Merge m-c to fx-team. a=merge

This commit is contained in:
Ryan VanderMeulen 2016-01-17 15:11:03 -05:00
commit a6e049875d
429 changed files with 12533 additions and 6243 deletions

View File

@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Bug 1133073 - Use PR_DuplicateEnvironment from NSPR and remove interim mozglue wrappers.
Bug 1228641 - Remove initializer_list from config/stl-headers

View File

@ -21,8 +21,8 @@
<!--
B2G repositories for all targets
-->
<project name="gaia" path="gaia" remote="mozillaorg" revision="be3b4cd7c8c4d38c3fa7ebc845bdb408b7bfcdbb"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b2faf0026571bb3cf9b8b3cb5a252911af951db6"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="ac6083c43e35eae958698e999630fa392f93cc63"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="35dccb3127db8f39f20b985ad312d2cd44780669"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
<!-- B2G specific things. -->

View File

@ -21,8 +21,8 @@
<!--
B2G repositories for all targets
-->
<project name="gaia" path="gaia" remote="mozillaorg" revision="be3b4cd7c8c4d38c3fa7ebc845bdb408b7bfcdbb"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b2faf0026571bb3cf9b8b3cb5a252911af951db6"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="ac6083c43e35eae958698e999630fa392f93cc63"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="35dccb3127db8f39f20b985ad312d2cd44780669"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
<!-- B2G specific things. -->

View File

@ -21,8 +21,8 @@
<!--
B2G repositories for all targets
-->
<project name="gaia" path="gaia" remote="mozillaorg" revision="be3b4cd7c8c4d38c3fa7ebc845bdb408b7bfcdbb"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b2faf0026571bb3cf9b8b3cb5a252911af951db6"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="ac6083c43e35eae958698e999630fa392f93cc63"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="35dccb3127db8f39f20b985ad312d2cd44780669"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
<!-- B2G specific things. -->

View File

@ -21,8 +21,8 @@
<!--
B2G repositories for all targets
-->
<project name="gaia" path="gaia" remote="mozillaorg" revision="be3b4cd7c8c4d38c3fa7ebc845bdb408b7bfcdbb"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b2faf0026571bb3cf9b8b3cb5a252911af951db6"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="ac6083c43e35eae958698e999630fa392f93cc63"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="35dccb3127db8f39f20b985ad312d2cd44780669"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
<default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>

View File

@ -21,8 +21,8 @@
<!--
B2G repositories for all targets
-->
<project name="gaia" path="gaia" remote="mozillaorg" revision="be3b4cd7c8c4d38c3fa7ebc845bdb408b7bfcdbb"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b2faf0026571bb3cf9b8b3cb5a252911af951db6"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="ac6083c43e35eae958698e999630fa392f93cc63"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="35dccb3127db8f39f20b985ad312d2cd44780669"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
<!-- B2G specific things. -->

View File

@ -21,8 +21,8 @@
<!--
B2G repositories for all targets
-->
<project name="gaia" path="gaia" remote="mozillaorg" revision="be3b4cd7c8c4d38c3fa7ebc845bdb408b7bfcdbb"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b2faf0026571bb3cf9b8b3cb5a252911af951db6"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="ac6083c43e35eae958698e999630fa392f93cc63"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="35dccb3127db8f39f20b985ad312d2cd44780669"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
<!-- B2G specific things. -->

View File

@ -21,8 +21,8 @@
<!--
B2G repositories for all targets
-->
<project name="gaia" path="gaia" remote="mozillaorg" revision="be3b4cd7c8c4d38c3fa7ebc845bdb408b7bfcdbb"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b2faf0026571bb3cf9b8b3cb5a252911af951db6"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="ac6083c43e35eae958698e999630fa392f93cc63"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="35dccb3127db8f39f20b985ad312d2cd44780669"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
<!-- B2G specific things. -->

View File

@ -21,8 +21,8 @@
<!--
B2G repositories for all targets
-->
<project name="gaia" path="gaia" remote="mozillaorg" revision="be3b4cd7c8c4d38c3fa7ebc845bdb408b7bfcdbb"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b2faf0026571bb3cf9b8b3cb5a252911af951db6"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="ac6083c43e35eae958698e999630fa392f93cc63"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="35dccb3127db8f39f20b985ad312d2cd44780669"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
<default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>

View File

@ -21,8 +21,8 @@
<!--
B2G repositories for all targets
-->
<project name="gaia" path="gaia" remote="mozillaorg" revision="be3b4cd7c8c4d38c3fa7ebc845bdb408b7bfcdbb"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b2faf0026571bb3cf9b8b3cb5a252911af951db6"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="ac6083c43e35eae958698e999630fa392f93cc63"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="35dccb3127db8f39f20b985ad312d2cd44780669"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
<!-- B2G specific things. -->

View File

@ -1,9 +1,9 @@
{
"git": {
"git_revision": "be3b4cd7c8c4d38c3fa7ebc845bdb408b7bfcdbb",
"git_revision": "ac6083c43e35eae958698e999630fa392f93cc63",
"remote": "https://git.mozilla.org/releases/gaia.git",
"branch": ""
},
"revision": "f9352eba9bf1091faf7b933213968a9eb441ed60",
"revision": "9b062139918bbf3efd1be026eabb64c260d27699",
"repo_path": "integration/gaia-central"
}

View File

@ -21,8 +21,8 @@
<!--
B2G repositories for all targets
-->
<project name="gaia" path="gaia" remote="mozillaorg" revision="be3b4cd7c8c4d38c3fa7ebc845bdb408b7bfcdbb"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b2faf0026571bb3cf9b8b3cb5a252911af951db6"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="ac6083c43e35eae958698e999630fa392f93cc63"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="35dccb3127db8f39f20b985ad312d2cd44780669"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
<!-- B2G specific things. -->

View File

@ -21,8 +21,8 @@
<!--
B2G repositories for all targets
-->
<project name="gaia" path="gaia" remote="mozillaorg" revision="be3b4cd7c8c4d38c3fa7ebc845bdb408b7bfcdbb"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b2faf0026571bb3cf9b8b3cb5a252911af951db6"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="ac6083c43e35eae958698e999630fa392f93cc63"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="35dccb3127db8f39f20b985ad312d2cd44780669"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
<!-- B2G specific things. -->

View File

@ -21,8 +21,8 @@
<!--
B2G repositories for all targets
-->
<project name="gaia" path="gaia" remote="mozillaorg" revision="be3b4cd7c8c4d38c3fa7ebc845bdb408b7bfcdbb"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="b2faf0026571bb3cf9b8b3cb5a252911af951db6"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="ac6083c43e35eae958698e999630fa392f93cc63"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="35dccb3127db8f39f20b985ad312d2cd44780669"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
<!-- B2G specific things. -->
@ -152,7 +152,7 @@
<default remote="caf" revision="refs/tags/android-5.1.0_r1" sync-j="4"/>
<!-- Nexus 5 specific things -->
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="fe7df1bc8dd0fd71571505d7be1c31a4ad1e40fb"/>
<project name="device-hammerhead" path="device/lge/hammerhead" remote="b2g" revision="1401762a4eea0b92141e8ff3100f93e9d6556fc8"/>
<project name="device-hammerhead" path="device/lge/hammerhead" remote="b2g" revision="bd18d073ab711f2c9f7f3c352f00b19acd10f5ae"/>
<project name="device_lge_hammerhead-kernel" path="device/lge/hammerhead-kernel" remote="b2g" revision="8b3ffcfdd3d3852eca5488628f8bb2a08acbffa7"/>
<project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="5d0ae53d9588c3d70c005aec9be94af9a534de16"/>
<project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="c15b6e266136cd0cdd9b94d0bbed1962d9dd6672"/>

View File

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1452200089000">
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1452810773000">
<emItems>
<emItem blockID="i58" id="webmaster@buzzzzvideos.info">
<versionRange minVersion="0" maxVersion="*">
@ -2532,6 +2532,12 @@
</versionRange>
<prefs>
</prefs>
</emItem>
<emItem blockID="i1077" id="helper@vidscrab.com">
<versionRange minVersion="0" maxVersion="*" severity="1">
</versionRange>
<prefs>
</prefs>
</emItem>
<emItem blockID="i15" id="personas@christopher.beard">
<versionRange minVersion="1.6" maxVersion="1.6">

View File

@ -21,7 +21,8 @@ AC_DEFUN([MOZ_SET_FRAMEPTR_FLAGS], [
fi
else
case "$target" in
*-mingw*)
dnl Oy (Frame-Pointer Omission) is only support on x86 compilers
*-mingw32*)
MOZ_ENABLE_FRAME_PTR="-Oy-"
MOZ_DISABLE_FRAME_PTR="-Oy"
;;

View File

@ -66,19 +66,14 @@ SEARCH_PATHS = [
'dom/bindings/parser',
'layout/tools/reftest',
'other-licenses/ply',
'xpcom/idl-parser',
'testing',
'testing/tools/autotry',
'testing/taskcluster',
'testing/xpcshell',
'testing/web-platform',
'testing/web-platform/harness',
'testing/web-platform/tests/tools/wptserve',
'testing/firefox-ui/harness',
'testing/firefox-ui/tests',
'testing/luciddream',
'testing/marionette/client',
'testing/marionette/client/marionette/runner/mixins/browsermob-proxy-py',
'testing/marionette/transport',
'testing/marionette/driver',
'testing/luciddream',
'testing/mozbase/mozcrash',
'testing/mozbase/mozdebug',
'testing/mozbase/mozdevice',
@ -97,6 +92,13 @@ SEARCH_PATHS = [
'testing/mozbase/moztest',
'testing/mozbase/mozversion',
'testing/mozbase/manifestparser',
'testing/puppeteer/firefox',
'testing/taskcluster',
'testing/tools/autotry',
'testing/web-platform',
'testing/web-platform/harness',
'testing/web-platform/tests/tools/wptserve',
'testing/xpcshell',
'xpcom/idl-parser',
]
@ -115,14 +117,14 @@ MACH_MODULES = [
'python/mozbuild/mozbuild/compilation/codecomplete.py',
'python/mozbuild/mozbuild/frontend/mach_commands.py',
'services/common/tests/mach_commands.py',
'testing/firefox-ui/mach_commands.py',
'testing/luciddream/mach_commands.py',
'testing/mach_commands.py',
'testing/taskcluster/mach_commands.py',
'testing/marionette/mach_commands.py',
'testing/mochitest/mach_commands.py',
'testing/mozharness/mach_commands.py',
'testing/xpcshell/mach_commands.py',
'testing/talos/mach_commands.py',
'testing/taskcluster/mach_commands.py',
'testing/web-platform/mach_commands.py',
'testing/xpcshell/mach_commands.py',
'tools/docs/mach_commands.py',

View File

@ -467,7 +467,7 @@ nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction(JSContext *cx)
unsigned lineNum = 0;
NS_NAMED_LITERAL_STRING(scriptSample, "call to eval() or related function blocked by CSP");
JS::AutoFilename scriptFilename;
JS::UniqueChars scriptFilename;
if (JS::DescribeScriptedCaller(cx, &scriptFilename, &lineNum)) {
if (const char *file = scriptFilename.get()) {
CopyUTF8toUTF16(nsDependentCString(file), fileName);

View File

@ -20,7 +20,6 @@ new
algorithm
atomic
deque
initializer_list
ios
iosfwd
iostream

View File

@ -75,7 +75,7 @@ GNOMEUI_VERSION=2.2.0
GCONF_VERSION=1.2.1
STARTUP_NOTIFICATION_VERSION=0.8
DBUS_VERSION=0.60
SQLITE_VERSION=3.9.1
SQLITE_VERSION=3.10.1
MSMANIFEST_TOOL=
@ -1457,6 +1457,7 @@ if test "$GNU_CC"; then
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wpointer-arith"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wtype-limits"
# -Wclass-varargs - catches objects passed by value to variadic functions.
# -Wnon-literal-null-conversion - catches expressions used as a null pointer constant
# -Wsometimes-initialized - catches some uninitialized values
# -Wunreachable-code-aggressive - catches lots of dead code
@ -1468,6 +1469,8 @@ if test "$GNU_CC"; then
# -Werror=non-literal-null-conversion, but we only do that when
# --enable-warnings-as-errors is specified so that no unexpected fatal
# warnings are produced.
MOZ_C_SUPPORTS_WARNING(-W, class-varargs, ac_c_has_wclass_varargs)
if test "$MOZ_ENABLE_WARNINGS_AS_ERRORS"; then
MOZ_C_SUPPORTS_WARNING(-Werror=, non-literal-null-conversion, ac_c_has_non_literal_null_conversion)
fi
@ -1541,6 +1544,7 @@ if test "$GNU_CXX"; then
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wpointer-arith"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wtype-limits"
# -Wclass-varargs - catches objects passed by value to variadic functions.
# -Wnon-literal-null-conversion - catches expressions used as a null pointer constant
# -Wrange-loop-analysis - catches copies during range-based for loops.
# -Wsometimes-initialized - catches some uninitialized values
@ -1554,6 +1558,8 @@ if test "$GNU_CXX"; then
# -Werror=non-literal-null-conversion, but we only do that when
# --enable-warnings-as-errors is specified so that no unexpected fatal
# warnings are produced.
MOZ_CXX_SUPPORTS_WARNING(-W, class-varargs, ac_cxx_has_wclass_varargs)
if test "$MOZ_ENABLE_WARNINGS_AS_ERRORS"; then
MOZ_CXX_SUPPORTS_WARNING(-Werror=, non-literal-null-conversion, ac_cxx_has_non_literal_null_conversion)
fi

File diff suppressed because it is too large Load Diff

View File

@ -111,9 +111,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION "3.9.1"
#define SQLITE_VERSION_NUMBER 3009001
#define SQLITE_SOURCE_ID "2015-10-16 17:31:12 767c1727fec4ce11b83f25b3f1bfcfe68a2c8b02"
#define SQLITE_VERSION "3.10.1"
#define SQLITE_VERSION_NUMBER 3010001
#define SQLITE_SOURCE_ID "2016-01-13 21:41:56 254419c36766225ca542ae873ed38255e3fb8588"
/*
** CAPI3REF: Run-Time Library Version Numbers
@ -478,6 +478,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_exec(
#define SQLITE_IOERR_GETTEMPPATH (SQLITE_IOERR | (25<<8))
#define SQLITE_IOERR_CONVPATH (SQLITE_IOERR | (26<<8))
#define SQLITE_IOERR_VNODE (SQLITE_IOERR | (27<<8))
#define SQLITE_IOERR_AUTH (SQLITE_IOERR | (28<<8))
#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
#define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8))
@ -793,8 +794,13 @@ struct sqlite3_io_methods {
** <li>[[SQLITE_FCNTL_FILE_POINTER]]
** The [SQLITE_FCNTL_FILE_POINTER] opcode is used to obtain a pointer
** to the [sqlite3_file] object associated with a particular database
** connection. See the [sqlite3_file_control()] documentation for
** additional information.
** connection. See also [SQLITE_FCNTL_JOURNAL_POINTER].
**
** <li>[[SQLITE_FCNTL_JOURNAL_POINTER]]
** The [SQLITE_FCNTL_JOURNAL_POINTER] opcode is used to obtain a pointer
** to the [sqlite3_file] object associated with the journal file (either
** the [rollback journal] or the [write-ahead log]) for a particular database
** connection. See also [SQLITE_FCNTL_FILE_POINTER].
**
** <li>[[SQLITE_FCNTL_SYNC_OMITTED]]
** No longer in use.
@ -881,6 +887,15 @@ struct sqlite3_io_methods {
** pointer in case this file-control is not implemented. This file-control
** is intended for diagnostic use only.
**
** <li>[[SQLITE_FCNTL_VFS_POINTER]]
** ^The [SQLITE_FCNTL_VFS_POINTER] opcode finds a pointer to the top-level
** [VFSes] currently in use. ^(The argument X in
** sqlite3_file_control(db,SQLITE_FCNTL_VFS_POINTER,X) must be
** of type "[sqlite3_vfs] **". This opcodes will set *X
** to a pointer to the top-level VFS.)^
** ^When there are multiple VFS shims in the stack, this opcode finds the
** upper-most shim only.
**
** <li>[[SQLITE_FCNTL_PRAGMA]]
** ^Whenever a [PRAGMA] statement is parsed, an [SQLITE_FCNTL_PRAGMA]
** file control is sent to the open [sqlite3_file] object corresponding
@ -999,6 +1014,8 @@ struct sqlite3_io_methods {
#define SQLITE_FCNTL_WAL_BLOCK 24
#define SQLITE_FCNTL_ZIPVFS 25
#define SQLITE_FCNTL_RBU 26
#define SQLITE_FCNTL_VFS_POINTER 27
#define SQLITE_FCNTL_JOURNAL_POINTER 28
/* deprecated names */
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
@ -1598,29 +1615,34 @@ struct sqlite3_mem_methods {
** </dd>
**
** [[SQLITE_CONFIG_PAGECACHE]] <dt>SQLITE_CONFIG_PAGECACHE</dt>
** <dd> ^The SQLITE_CONFIG_PAGECACHE option specifies a static memory buffer
** <dd> ^The SQLITE_CONFIG_PAGECACHE option specifies a memory pool
** that SQLite can use for the database page cache with the default page
** cache implementation.
** This configuration should not be used if an application-define page
** cache implementation is loaded using the [SQLITE_CONFIG_PCACHE2]
** configuration option.
** This configuration option is a no-op if an application-define page
** cache implementation is loaded using the [SQLITE_CONFIG_PCACHE2].
** ^There are three arguments to SQLITE_CONFIG_PAGECACHE: A pointer to
** 8-byte aligned
** memory, the size of each page buffer (sz), and the number of pages (N).
** 8-byte aligned memory (pMem), the size of each page cache line (sz),
** and the number of cache lines (N).
** The sz argument should be the size of the largest database page
** (a power of two between 512 and 65536) plus some extra bytes for each
** page header. ^The number of extra bytes needed by the page header
** can be determined using the [SQLITE_CONFIG_PCACHE_HDRSZ] option
** to [sqlite3_config()].
** can be determined using [SQLITE_CONFIG_PCACHE_HDRSZ].
** ^It is harmless, apart from the wasted memory,
** for the sz parameter to be larger than necessary. The first
** argument should pointer to an 8-byte aligned block of memory that
** is at least sz*N bytes of memory, otherwise subsequent behavior is
** undefined.
** ^SQLite will use the memory provided by the first argument to satisfy its
** memory needs for the first N pages that it adds to cache. ^If additional
** page cache memory is needed beyond what is provided by this option, then
** SQLite goes to [sqlite3_malloc()] for the additional storage space.</dd>
** for the sz parameter to be larger than necessary. The pMem
** argument must be either a NULL pointer or a pointer to an 8-byte
** aligned block of memory of at least sz*N bytes, otherwise
** subsequent behavior is undefined.
** ^When pMem is not NULL, SQLite will strive to use the memory provided
** to satisfy page cache needs, falling back to [sqlite3_malloc()] if
** a page cache line is larger than sz bytes or if all of the pMem buffer
** is exhausted.
** ^If pMem is NULL and N is non-zero, then each database connection
** does an initial bulk allocation for page cache memory
** from [sqlite3_malloc()] sufficient for N cache lines if N is positive or
** of -1024*N bytes if N is negative, . ^If additional
** page cache memory is needed beyond what is provided by the initial
** allocation, then SQLite goes to [sqlite3_malloc()] separately for each
** additional cache line. </dd>
**
** [[SQLITE_CONFIG_HEAP]] <dt>SQLITE_CONFIG_HEAP</dt>
** <dd> ^The SQLITE_CONFIG_HEAP option specifies a static memory buffer
@ -4389,8 +4411,8 @@ SQLITE_API unsigned int SQLITE_STDCALL sqlite3_value_subtype(sqlite3_value*);
** previously obtained from [sqlite3_value_dup()]. ^If V is a NULL pointer
** then sqlite3_value_free(V) is a harmless no-op.
*/
SQLITE_API SQLITE_EXPERIMENTAL sqlite3_value *SQLITE_STDCALL sqlite3_value_dup(const sqlite3_value*);
SQLITE_API SQLITE_EXPERIMENTAL void SQLITE_STDCALL sqlite3_value_free(sqlite3_value*);
SQLITE_API sqlite3_value *SQLITE_STDCALL sqlite3_value_dup(const sqlite3_value*);
SQLITE_API void SQLITE_STDCALL sqlite3_value_free(sqlite3_value*);
/*
** CAPI3REF: Obtain Aggregate Function Context
@ -5609,6 +5631,17 @@ struct sqlite3_module {
** ^Information about the ORDER BY clause is stored in aOrderBy[].
** ^Each term of aOrderBy records a column of the ORDER BY clause.
**
** The colUsed field indicates which columns of the virtual table may be
** required by the current scan. Virtual table columns are numbered from
** zero in the order in which they appear within the CREATE TABLE statement
** passed to sqlite3_declare_vtab(). For the first 63 columns (columns 0-62),
** the corresponding bit is set within the colUsed mask if the column may be
** required by SQLite. If the table has at least 64 columns and any column
** to the right of the first 63 is required, then bit 63 of colUsed is also
** set. In other words, column iCol may be required if the expression
** (colUsed & ((sqlite3_uint64)1 << (iCol>=63 ? 63 : iCol))) evaluates to
** non-zero.
**
** The [xBestIndex] method must fill aConstraintUsage[] with information
** about what parameters to pass to xFilter. ^If argvIndex>0 then
** the right-hand side of the corresponding aConstraint[] is evaluated
@ -5688,6 +5721,8 @@ struct sqlite3_index_info {
sqlite3_int64 estimatedRows; /* Estimated number of rows returned */
/* Fields below are only available in SQLite 3.9.0 and later */
int idxFlags; /* Mask of SQLITE_INDEX_SCAN_* flags */
/* Fields below are only available in SQLite 3.10.0 and later */
sqlite3_uint64 colUsed; /* Input: Mask of columns used by statement */
};
/*
@ -5703,12 +5738,15 @@ struct sqlite3_index_info {
** an operator that is part of a constraint term in the wHERE clause of
** a query that uses a [virtual table].
*/
#define SQLITE_INDEX_CONSTRAINT_EQ 2
#define SQLITE_INDEX_CONSTRAINT_GT 4
#define SQLITE_INDEX_CONSTRAINT_LE 8
#define SQLITE_INDEX_CONSTRAINT_LT 16
#define SQLITE_INDEX_CONSTRAINT_GE 32
#define SQLITE_INDEX_CONSTRAINT_MATCH 64
#define SQLITE_INDEX_CONSTRAINT_EQ 2
#define SQLITE_INDEX_CONSTRAINT_GT 4
#define SQLITE_INDEX_CONSTRAINT_LE 8
#define SQLITE_INDEX_CONSTRAINT_LT 16
#define SQLITE_INDEX_CONSTRAINT_GE 32
#define SQLITE_INDEX_CONSTRAINT_MATCH 64
#define SQLITE_INDEX_CONSTRAINT_LIKE 65
#define SQLITE_INDEX_CONSTRAINT_GLOB 66
#define SQLITE_INDEX_CONSTRAINT_REGEXP 67
/*
** CAPI3REF: Register A Virtual Table Implementation
@ -6572,7 +6610,8 @@ SQLITE_API int SQLITE_STDCALL sqlite3_status64(
** The value written into the *pCurrent parameter is undefined.</dd>)^
**
** [[SQLITE_STATUS_PARSER_STACK]] ^(<dt>SQLITE_STATUS_PARSER_STACK</dt>
** <dd>This parameter records the deepest parser stack. It is only
** <dd>The *pHighwater parameter records the deepest parser stack.
** The *pCurrent value is undefined. The *pHighwater value is only
** meaningful if SQLite is compiled with [YYTRACKMAXSTACKDEPTH].</dd>)^
** </dl>
**
@ -7358,18 +7397,43 @@ SQLITE_API int SQLITE_STDCALL sqlite3_strnicmp(const char *, const char *, int);
/*
** CAPI3REF: String Globbing
*
** ^The [sqlite3_strglob(P,X)] interface returns zero if string X matches
** the glob pattern P, and it returns non-zero if string X does not match
** the glob pattern P. ^The definition of glob pattern matching used in
** ^The [sqlite3_strglob(P,X)] interface returns zero if and only if
** string X matches the [GLOB] pattern P.
** ^The definition of [GLOB] pattern matching used in
** [sqlite3_strglob(P,X)] is the same as for the "X GLOB P" operator in the
** SQL dialect used by SQLite. ^The sqlite3_strglob(P,X) function is case
** sensitive.
** SQL dialect understood by SQLite. ^The [sqlite3_strglob(P,X)] function
** is case sensitive.
**
** Note that this routine returns zero on a match and non-zero if the strings
** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()].
**
** See also: [sqlite3_strlike()].
*/
SQLITE_API int SQLITE_STDCALL sqlite3_strglob(const char *zGlob, const char *zStr);
/*
** CAPI3REF: String LIKE Matching
*
** ^The [sqlite3_strlike(P,X,E)] interface returns zero if and only if
** string X matches the [LIKE] pattern P with escape character E.
** ^The definition of [LIKE] pattern matching used in
** [sqlite3_strlike(P,X,E)] is the same as for the "X LIKE P ESCAPE E"
** operator in the SQL dialect understood by SQLite. ^For "X LIKE P" without
** the ESCAPE clause, set the E parameter of [sqlite3_strlike(P,X,E)] to 0.
** ^As with the LIKE operator, the [sqlite3_strlike(P,X,E)] function is case
** insensitive - equivalent upper and lower case ASCII characters match
** one another.
**
** ^The [sqlite3_strlike(P,X,E)] function matches Unicode characters, though
** only ASCII characters are case folded.
**
** Note that this routine returns zero on a match and non-zero if the strings
** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()].
**
** See also: [sqlite3_strglob()].
*/
SQLITE_API int SQLITE_STDCALL sqlite3_strlike(const char *zGlob, const char *zStr, unsigned int cEsc);
/*
** CAPI3REF: Error Logging Interface
**
@ -7790,6 +7854,129 @@ SQLITE_API int SQLITE_STDCALL sqlite3_stmt_scanstatus(
*/
SQLITE_API void SQLITE_STDCALL sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
/*
** CAPI3REF: Flush caches to disk mid-transaction
**
** ^If a write-transaction is open on [database connection] D when the
** [sqlite3_db_cacheflush(D)] interface invoked, any dirty
** pages in the pager-cache that are not currently in use are written out
** to disk. A dirty page may be in use if a database cursor created by an
** active SQL statement is reading from it, or if it is page 1 of a database
** file (page 1 is always "in use"). ^The [sqlite3_db_cacheflush(D)]
** interface flushes caches for all schemas - "main", "temp", and
** any [attached] databases.
**
** ^If this function needs to obtain extra database locks before dirty pages
** can be flushed to disk, it does so. ^If those locks cannot be obtained
** immediately and there is a busy-handler callback configured, it is invoked
** in the usual manner. ^If the required lock still cannot be obtained, then
** the database is skipped and an attempt made to flush any dirty pages
** belonging to the next (if any) database. ^If any databases are skipped
** because locks cannot be obtained, but no other error occurs, this
** function returns SQLITE_BUSY.
**
** ^If any other error occurs while flushing dirty pages to disk (for
** example an IO error or out-of-memory condition), then processing is
** abandoned and an SQLite [error code] is returned to the caller immediately.
**
** ^Otherwise, if no error occurs, [sqlite3_db_cacheflush()] returns SQLITE_OK.
**
** ^This function does not set the database handle error code or message
** returned by the [sqlite3_errcode()] and [sqlite3_errmsg()] functions.
*/
SQLITE_API int SQLITE_STDCALL sqlite3_db_cacheflush(sqlite3*);
/*
** CAPI3REF: Database Snapshot
** KEYWORDS: {snapshot}
** EXPERIMENTAL
**
** An instance of the snapshot object records the state of a [WAL mode]
** database for some specific point in history.
**
** In [WAL mode], multiple [database connections] that are open on the
** same database file can each be reading a different historical version
** of the database file. When a [database connection] begins a read
** transaction, that connection sees an unchanging copy of the database
** as it existed for the point in time when the transaction first started.
** Subsequent changes to the database from other connections are not seen
** by the reader until a new read transaction is started.
**
** The sqlite3_snapshot object records state information about an historical
** version of the database file so that it is possible to later open a new read
** transaction that sees that historical version of the database rather than
** the most recent version.
**
** The constructor for this object is [sqlite3_snapshot_get()]. The
** [sqlite3_snapshot_open()] method causes a fresh read transaction to refer
** to an historical snapshot (if possible). The destructor for
** sqlite3_snapshot objects is [sqlite3_snapshot_free()].
*/
typedef struct sqlite3_snapshot sqlite3_snapshot;
/*
** CAPI3REF: Record A Database Snapshot
** EXPERIMENTAL
**
** ^The [sqlite3_snapshot_get(D,S,P)] interface attempts to make a
** new [sqlite3_snapshot] object that records the current state of
** schema S in database connection D. ^On success, the
** [sqlite3_snapshot_get(D,S,P)] interface writes a pointer to the newly
** created [sqlite3_snapshot] object into *P and returns SQLITE_OK.
** ^If schema S of [database connection] D is not a [WAL mode] database
** that is in a read transaction, then [sqlite3_snapshot_get(D,S,P)]
** leaves the *P value unchanged and returns an appropriate [error code].
**
** The [sqlite3_snapshot] object returned from a successful call to
** [sqlite3_snapshot_get()] must be freed using [sqlite3_snapshot_free()]
** to avoid a memory leak.
**
** The [sqlite3_snapshot_get()] interface is only available when the
** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
*/
SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_snapshot_get(
sqlite3 *db,
const char *zSchema,
sqlite3_snapshot **ppSnapshot
);
/*
** CAPI3REF: Start a read transaction on an historical snapshot
** EXPERIMENTAL
**
** ^The [sqlite3_snapshot_open(D,S,P)] interface attempts to move the
** read transaction that is currently open on schema S of
** [database connection] D so that it refers to historical [snapshot] P.
** ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK on success
** or an appropriate [error code] if it fails.
**
** ^In order to succeed, a call to [sqlite3_snapshot_open(D,S,P)] must be
** the first operation, apart from other sqlite3_snapshot_open() calls,
** following the [BEGIN] that starts a new read transaction.
** ^A [snapshot] will fail to open if it has been overwritten by a
** [checkpoint].
**
** The [sqlite3_snapshot_open()] interface is only available when the
** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
*/
SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_snapshot_open(
sqlite3 *db,
const char *zSchema,
sqlite3_snapshot *pSnapshot
);
/*
** CAPI3REF: Destroy a snapshot
** EXPERIMENTAL
**
** ^The [sqlite3_snapshot_free(P)] interface destroys [sqlite3_snapshot] P.
** The application must eventually free every [sqlite3_snapshot] object
** using this routine to avoid a memory leak.
**
** The [sqlite3_snapshot_free()] interface is only available when the
** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
*/
SQLITE_API SQLITE_EXPERIMENTAL void SQLITE_STDCALL sqlite3_snapshot_free(sqlite3_snapshot*);
/*
** Undo the hack that converts floating point types to integer for

View File

@ -120,16 +120,15 @@ Concrete<DeserializedNode>::allocationStack() const
}
UniquePtr<EdgeRange>
js::UniquePtr<EdgeRange>
Concrete<DeserializedNode>::edges(JSRuntime* rt, bool) const
{
UniquePtr<DeserializedEdgeRange, JS::DeletePolicy<DeserializedEdgeRange>> range(
js_new<DeserializedEdgeRange>(get()));
js::UniquePtr<DeserializedEdgeRange> range(js_new<DeserializedEdgeRange>(get()));
if (!range)
return nullptr;
return UniquePtr<EdgeRange>(range.release());
return js::UniquePtr<EdgeRange>(range.release());
}
StackFrame

View File

@ -7,10 +7,10 @@
#define mozilla_devtools_DeserializedNode__
#include "js/UbiNode.h"
#include "js/UniquePtr.h"
#include "mozilla/devtools/CoreDump.pb.h"
#include "mozilla/Maybe.h"
#include "mozilla/Move.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/Vector.h"
// `Deserialized{Node,Edge}` translate protobuf messages from our core dump
@ -242,7 +242,6 @@ namespace ubi {
using mozilla::devtools::DeserializedNode;
using mozilla::devtools::DeserializedStackFrame;
using mozilla::UniquePtr;
template<>
struct Concrete<DeserializedNode> : public Base
@ -273,7 +272,7 @@ public:
// We ignore the `bool wantNames` parameter because we can't control whether
// the core dump was serialized with edge names or not.
UniquePtr<EdgeRange> edges(JSRuntime* rt, bool) const override;
js::UniquePtr<EdgeRange> edges(JSRuntime* rt, bool) const override;
};
template<>

View File

@ -17,9 +17,9 @@
#include "mozilla/dom/ChromeUtils.h"
#include "mozilla/CycleCollectedJSRuntime.h"
#include "mozilla/Move.h"
#include "mozilla/UniquePtr.h"
#include "js/Principals.h"
#include "js/UbiNode.h"
#include "js/UniquePtr.h"
using namespace mozilla;
using namespace mozilla::devtools;
@ -173,8 +173,6 @@ public:
namespace JS {
namespace ubi {
using mozilla::UniquePtr;
template<>
class Concrete<FakeNode> : public Base
{
@ -182,8 +180,8 @@ class Concrete<FakeNode> : public Base
return concreteTypeName;
}
UniquePtr<EdgeRange> edges(JSRuntime*, bool) const override {
return UniquePtr<EdgeRange>(js_new<PreComputedEdgeRange>(get().edges));
js::UniquePtr<EdgeRange> edges(JSRuntime*, bool) const override {
return js::UniquePtr<EdgeRange>(js_new<PreComputedEdgeRange>(get().edges));
}
Size size(mozilla::MallocSizeOf) const override {

View File

@ -805,6 +805,7 @@ nsDocShell::nsDocShell()
, mBlankTiming(false)
, mFrameType(eFrameTypeRegular)
, mOwnOrContainingAppId(nsIScriptSecurityManager::UNKNOWN_APP_ID)
, mUserContextId(nsIScriptSecurityManager::DEFAULT_USER_CONTEXT_ID)
, mParentCharsetSource(0)
, mJSRunToCompletionDepth(0)
{
@ -14073,7 +14074,7 @@ nsDocShell::NotifyJSRunToCompletionStart(const char* aReason,
RefPtr<TimelineConsumers> timelines = TimelineConsumers::Get();
if (timelines && timelines->HasConsumer(this)) {
timelines->AddMarkerForDocShell(this, Move(
MakeUnique<JavascriptTimelineMarker>(
mozilla::MakeUnique<JavascriptTimelineMarker>(
aReason, aFunctionName, aFilename, aLineNumber, MarkerTracingType::START,
aAsyncStack, aAsyncCause)));
}

View File

@ -19,6 +19,7 @@
#include "nsIPresShell.h"
#include "nsLayoutUtils.h"
#include "nsRuleNode.h" // For nsRuleNode::ComputePropertiesOverridingAnimation
#include "nsRuleProcessorData.h" // For ElementRuleProcessorData etc.
#include "nsTArray.h"
#include "RestyleManager.h"
@ -236,22 +237,44 @@ EffectCompositor::GetAnimationRule(dom::Element* aElement,
nsCSSPseudoElements::Type aPseudoType,
CascadeLevel aCascadeLevel)
{
// NOTE: We need to be careful about early returns in this method where
// we *don't* update mElementsToRestyle. When we get a call to
// RequestRestyle that results in a call to PostRestyleForAnimation, we
// will set a bool flag in mElementsToRestyle indicating that we've
// called PostRestyleForAnimation so we don't need to call it again
// until that restyle happens. During that restyle, if we arrive here
// and *don't* update mElementsToRestyle we'll continue to skip calling
// PostRestyleForAnimation from RequestRestyle.
if (!mPresContext || !mPresContext->IsDynamic()) {
// For print or print preview, ignore animations.
return nullptr;
}
EffectSet* effectSet = EffectSet::GetEffectSet(aElement, aPseudoType);
if (!effectSet) {
return nullptr;
}
if (mPresContext->RestyleManager()->SkipAnimationRules()) {
// We don't need to worry about updating mElementsToRestyle in this case
// since this is not the animation restyle we requested when we called
// PostRestyleForAnimation (see comment at start of this method).
return nullptr;
}
MaybeUpdateAnimationRule(aElement, aPseudoType, aCascadeLevel);
#ifdef DEBUG
{
auto& elementsToRestyle = mElementsToRestyle[aCascadeLevel];
PseudoElementHashKey key = { aElement, aPseudoType };
MOZ_ASSERT(!elementsToRestyle.Contains(key),
"Element should no longer require a restyle after its "
"animation rule has been updated");
}
#endif
EffectSet* effectSet = EffectSet::GetEffectSet(aElement, aPseudoType);
if (!effectSet) {
return nullptr;
}
return effectSet->AnimationRule(aCascadeLevel);
}
@ -680,4 +703,110 @@ EffectCompositor::GetPresContext(Element* aElement)
return shell->GetPresContext();
}
// ---------------------------------------------------------
//
// Nested class: AnimationStyleRuleProcessor
//
// ---------------------------------------------------------
NS_IMPL_ISUPPORTS(EffectCompositor::AnimationStyleRuleProcessor,
nsIStyleRuleProcessor)
nsRestyleHint
EffectCompositor::AnimationStyleRuleProcessor::HasStateDependentStyle(
StateRuleProcessorData* aData)
{
return nsRestyleHint(0);
}
nsRestyleHint
EffectCompositor::AnimationStyleRuleProcessor::HasStateDependentStyle(
PseudoElementStateRuleProcessorData* aData)
{
return nsRestyleHint(0);
}
bool
EffectCompositor::AnimationStyleRuleProcessor::HasDocumentStateDependentStyle(
StateRuleProcessorData* aData)
{
return false;
}
nsRestyleHint
EffectCompositor::AnimationStyleRuleProcessor::HasAttributeDependentStyle(
AttributeRuleProcessorData* aData,
RestyleHintData& aRestyleHintDataResult)
{
return nsRestyleHint(0);
}
bool
EffectCompositor::AnimationStyleRuleProcessor::MediumFeaturesChanged(
nsPresContext* aPresContext)
{
return false;
}
void
EffectCompositor::AnimationStyleRuleProcessor::RulesMatching(
ElementRuleProcessorData* aData)
{
nsIStyleRule *rule =
mCompositor->GetAnimationRule(aData->mElement,
nsCSSPseudoElements::ePseudo_NotPseudoElement,
mCascadeLevel);
if (rule) {
aData->mRuleWalker->Forward(rule);
aData->mRuleWalker->CurrentNode()->SetIsAnimationRule();
}
}
void
EffectCompositor::AnimationStyleRuleProcessor::RulesMatching(
PseudoElementRuleProcessorData* aData)
{
if (aData->mPseudoType != nsCSSPseudoElements::ePseudo_before &&
aData->mPseudoType != nsCSSPseudoElements::ePseudo_after) {
return;
}
nsIStyleRule *rule =
mCompositor->GetAnimationRule(aData->mElement,
aData->mPseudoType,
mCascadeLevel);
if (rule) {
aData->mRuleWalker->Forward(rule);
aData->mRuleWalker->CurrentNode()->SetIsAnimationRule();
}
}
void
EffectCompositor::AnimationStyleRuleProcessor::RulesMatching(
AnonBoxRuleProcessorData* aData)
{
}
#ifdef MOZ_XUL
void
EffectCompositor::AnimationStyleRuleProcessor::RulesMatching(
XULTreeRuleProcessorData* aData)
{
}
#endif
size_t
EffectCompositor::AnimationStyleRuleProcessor::SizeOfExcludingThis(
MallocSizeOf aMallocSizeOf) const
{
return 0;
}
size_t
EffectCompositor::AnimationStyleRuleProcessor::SizeOfIncludingThis(
MallocSizeOf aMallocSizeOf) const
{
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
}
} // namespace mozilla

View File

@ -9,6 +9,7 @@
#include "mozilla/EnumeratedArray.h"
#include "mozilla/Maybe.h"
#include "mozilla/OwningNonNull.h"
#include "mozilla/Pair.h"
#include "mozilla/PseudoElementHashEntry.h"
#include "mozilla/RefPtr.h"
@ -16,6 +17,7 @@
#include "nsCSSPseudoElements.h"
#include "nsCycleCollectionParticipant.h"
#include "nsDataHashtable.h"
#include "nsIStyleRuleProcessor.h"
#include "nsTArray.h"
class nsCSSPropertySet;
@ -39,7 +41,13 @@ class EffectCompositor
public:
explicit EffectCompositor(nsPresContext* aPresContext)
: mPresContext(aPresContext)
{ }
{
for (size_t i = 0; i < kCascadeLevelCount; i++) {
CascadeLevel cascadeLevel = CascadeLevel(i);
mRuleProcessors[cascadeLevel] =
new AnimationStyleRuleProcessor(this, cascadeLevel);
}
}
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(EffectCompositor)
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(EffectCompositor)
@ -123,6 +131,11 @@ public:
// elements.
void AddStyleUpdatesTo(RestyleTracker& aTracker);
nsIStyleRuleProcessor* RuleProcessor(CascadeLevel aCascadeLevel) const
{
return mRuleProcessors[aCascadeLevel];
}
static bool HasAnimationsForCompositor(const nsIFrame* aFrame,
nsCSSProperty aProperty);
@ -214,6 +227,51 @@ private:
EnumeratedArray<CascadeLevel, CascadeLevel(kCascadeLevelCount),
nsDataHashtable<PseudoElementHashEntry, bool>>
mElementsToRestyle;
class AnimationStyleRuleProcessor final : public nsIStyleRuleProcessor
{
public:
AnimationStyleRuleProcessor(EffectCompositor* aCompositor,
CascadeLevel aCascadeLevel)
: mCompositor(aCompositor)
, mCascadeLevel(aCascadeLevel)
{
MOZ_ASSERT(aCompositor);
}
NS_DECL_ISUPPORTS
// nsIStyleRuleProcessor (parts)
nsRestyleHint HasStateDependentStyle(
StateRuleProcessorData* aData) override;
nsRestyleHint HasStateDependentStyle(
PseudoElementStateRuleProcessorData* aData) override;
bool HasDocumentStateDependentStyle(StateRuleProcessorData* aData) override;
nsRestyleHint HasAttributeDependentStyle(
AttributeRuleProcessorData* aData,
RestyleHintData& aRestyleHintDataResult) override;
bool MediumFeaturesChanged(nsPresContext* aPresContext) override;
void RulesMatching(ElementRuleProcessorData* aData) override;
void RulesMatching(PseudoElementRuleProcessorData* aData) override;
void RulesMatching(AnonBoxRuleProcessorData* aData) override;
#ifdef MOZ_XUL
void RulesMatching(XULTreeRuleProcessorData* aData) override;
#endif
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf)
const MOZ_MUST_OVERRIDE override;
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf)
const MOZ_MUST_OVERRIDE override;
private:
~AnimationStyleRuleProcessor() = default;
EffectCompositor* mCompositor;
CascadeLevel mCascadeLevel;
};
EnumeratedArray<CascadeLevel, CascadeLevel(kCascadeLevelCount),
OwningNonNull<AnimationStyleRuleProcessor>>
mRuleProcessors;
};
} // namespace mozilla

View File

@ -108,6 +108,24 @@ EffectSet::GetOrCreateEffectSet(dom::Element* aElement,
return effectSet;
}
/* static */ void
EffectSet::DestroyEffectSet(dom::Element* aElement,
nsCSSPseudoElements::Type aPseudoType)
{
nsIAtom* propName = GetEffectSetPropertyAtom(aPseudoType);
EffectSet* effectSet =
static_cast<EffectSet*>(aElement->GetProperty(propName));
if (!effectSet) {
return;
}
MOZ_ASSERT(!effectSet->IsBeingEnumerated(),
"Should not destroy an effect set while it is being enumerated");
effectSet = nullptr;
aElement->DeleteProperty(propName);
}
void
EffectSet::UpdateAnimationGeneration(nsPresContext* aPresContext)
{

View File

@ -8,6 +8,7 @@
#define mozilla_EffectSet_h
#include "mozilla/AnimValuesStyleRule.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/EffectCompositor.h"
#include "mozilla/EnumeratedArray.h"
#include "mozilla/TimeStamp.h"
@ -32,6 +33,7 @@ public:
EffectSet()
: mCascadeNeedsUpdate(false)
, mAnimationGeneration(0)
, mActiveIterators(0)
#ifdef DEBUG
, mCalledPropertyDtor(false)
#endif
@ -43,6 +45,9 @@ public:
{
MOZ_ASSERT(mCalledPropertyDtor,
"must call destructor through element property dtor");
MOZ_ASSERT(mActiveIterators == 0,
"Effect set should not be destroyed while it is being "
"enumerated");
MOZ_COUNT_DTOR(EffectSet);
}
static void PropertyDtor(void* aObject, nsIAtom* aPropertyName,
@ -56,6 +61,8 @@ public:
static EffectSet* GetEffectSet(const nsIFrame* aFrame);
static EffectSet* GetOrCreateEffectSet(dom::Element* aElement,
nsCSSPseudoElements::Type aPseudoType);
static void DestroyEffectSet(dom::Element* aElement,
nsCSSPseudoElements::Type aPseudoType);
void AddEffect(dom::KeyframeEffectReadOnly& aEffect);
void RemoveEffect(dom::KeyframeEffectReadOnly& aEffect);
@ -74,20 +81,35 @@ public:
class Iterator
{
public:
explicit Iterator(OwningEffectSet::Iterator&& aHashIterator)
: mHashIterator(mozilla::Move(aHashIterator))
, mIsEndIterator(false) { }
Iterator(Iterator&& aOther)
: mHashIterator(mozilla::Move(aOther.mHashIterator))
, mIsEndIterator(aOther.mIsEndIterator) { }
static Iterator EndIterator(OwningEffectSet::Iterator&& aHashIterator)
explicit Iterator(EffectSet& aEffectSet)
: mEffectSet(aEffectSet)
, mHashIterator(mozilla::Move(aEffectSet.mEffects.Iter()))
, mIsEndIterator(false)
{
Iterator result(mozilla::Move(aHashIterator));
mEffectSet.mActiveIterators++;
}
Iterator(Iterator&& aOther)
: mEffectSet(aOther.mEffectSet)
, mHashIterator(mozilla::Move(aOther.mHashIterator))
, mIsEndIterator(aOther.mIsEndIterator)
{
mEffectSet.mActiveIterators++;
}
static Iterator EndIterator(EffectSet& aEffectSet)
{
Iterator result(aEffectSet);
result.mIsEndIterator = true;
return result;
}
~Iterator()
{
MOZ_ASSERT(mEffectSet.mActiveIterators > 0);
mEffectSet.mActiveIterators--;
}
bool operator!=(const Iterator& aOther) const {
if (Done() || aOther.Done()) {
return Done() != aOther.Done();
@ -117,15 +139,19 @@ public:
return mIsEndIterator || mHashIterator.Done();
}
EffectSet& mEffectSet;
OwningEffectSet::Iterator mHashIterator;
bool mIsEndIterator;
};
Iterator begin() { return Iterator(mEffects.Iter()); }
Iterator end()
{
return Iterator::EndIterator(mEffects.Iter());
}
friend class Iterator;
Iterator begin() { return Iterator(*this); }
Iterator end() { return Iterator::EndIterator(*this); }
#ifdef DEBUG
bool IsBeingEnumerated() const { return mActiveIterators != 0; }
#endif
bool IsEmpty() const { return mEffects.IsEmpty(); }
RefPtr<AnimValuesStyleRule>& AnimationRule(EffectCompositor::CascadeLevel
@ -195,6 +221,10 @@ private:
// the animation manager.
uint64_t mAnimationGeneration;
// Track how many iterators are referencing this effect set when we are
// destroyed, we can assert that nothing is still pointing to us.
DebugOnly<uint64_t> mActiveIterators;
#ifdef DEBUG
bool mCalledPropertyDtor;
#endif

View File

@ -180,6 +180,14 @@ KeyframeEffectReadOnly::NotifyAnimationTimingUpdated()
RequestRestyle(mTarget, mPseudoType, restyleType,
mAnimation->CascadeLevel());
}
// If we're not relevant, we will have been removed from the EffectSet.
// As a result, when the restyle we requested above is fulfilled, our
// ComposeStyle will not get called and mProgressOnLastCompose will not
// be updated. Instead, we need to manually clear it.
if (!isRelevant) {
mProgressOnLastCompose.SetNull();
}
}
}
@ -613,6 +621,9 @@ KeyframeEffectReadOnly::UpdateTargetRegistration()
EffectSet* effectSet = EffectSet::GetEffectSet(mTarget, mPseudoType);
if (effectSet) {
effectSet->RemoveEffect(*this);
if (effectSet->IsEmpty()) {
EffectSet::DestroyEffectSet(mTarget, mPseudoType);
}
}
}
}

View File

@ -1256,7 +1256,7 @@ WebSocket::Constructor(const GlobalObject& aGlobal,
}
unsigned lineno, column;
JS::AutoFilename file;
JS::UniqueChars file;
if (!JS::DescribeScriptedCaller(aGlobal.Context(), &file, &lineno,
&column)) {
NS_WARNING("Failed to get line number and filename in workers.");
@ -1491,7 +1491,7 @@ WebSocketImpl::Init(JSContext* aCx,
MOZ_ASSERT(aCx);
unsigned lineno, column;
JS::AutoFilename file;
JS::UniqueChars file;
if (JS::DescribeScriptedCaller(aCx, &file, &lineno, &column)) {
mScriptFile = file.get();
mScriptLine = lineno;

View File

@ -6636,6 +6636,48 @@ nsContentUtils::FindInternalContentViewer(const nsACString& aType,
return nullptr;
}
static void
ReportPatternCompileFailure(nsAString& aPattern, nsIDocument* aDocument,
JSContext* cx)
{
MOZ_ASSERT(JS_IsExceptionPending(cx));
JS::RootedValue exn(cx);
if (!JS_GetPendingException(cx, &exn)) {
return;
}
if (!exn.isObject()) {
// If pending exception is not an object, it should be OOM.
return;
}
JS::AutoSaveExceptionState savedExc(cx);
JS::RootedObject exnObj(cx, &exn.toObject());
JS::RootedValue messageVal(cx);
if (!JS_GetProperty(cx, exnObj, "message", &messageVal)) {
return;
}
MOZ_ASSERT(messageVal.isString());
JS::RootedString messageStr(cx, messageVal.toString());
MOZ_ASSERT(messageStr);
nsAutoString wideMessage;
if (!AssignJSString(cx, wideMessage, messageStr)) {
return;
}
const nsString& pattern = PromiseFlatString(aPattern);
const char16_t *strings[] = { pattern.get(), wideMessage.get() };
nsContentUtils::ReportToConsole(nsIScriptError::errorFlag,
NS_LITERAL_CSTRING("DOM"),
aDocument,
nsContentUtils::eDOM_PROPERTIES,
"PatternAttributeCompileFailure",
strings, ArrayLength(strings));
savedExc.drop();
}
// static
bool
nsContentUtils::IsPatternMatching(nsAString& aValue, nsAString& aPattern,
@ -6662,8 +6704,12 @@ nsContentUtils::IsPatternMatching(nsAString& aValue, nsAString& aPattern,
JS::Rooted<JSObject*> re(cx,
JS_NewUCRegExpObjectNoStatics(cx,
static_cast<char16_t*>(aPattern.BeginWriting()),
aPattern.Length(), 0));
aPattern.Length(), JSREG_UNICODE));
if (!re) {
// Remove extra patterns added above to report with the original pattern.
aPattern.Cut(0, 4);
aPattern.Cut(aPattern.Length() - 2, 2);
ReportPatternCompileFailure(aPattern, aDocument, cx);
return true;
}

View File

@ -196,6 +196,12 @@ nsDOMAttributeMap::GetSupportedNames(unsigned aFlags,
return;
}
// For HTML elements in HTML documents, only include names that are still the
// same after ASCII-lowercasing, since our named getter will end up
// ASCII-lowercasing the given string.
bool lowercaseNamesOnly =
mContent->IsHTMLElement() && mContent->IsInHTMLDocument();
const uint32_t count = mContent->GetAttrCount();
bool seenNonAtomName = false;
for (uint32_t i = 0; i < count; i++) {
@ -204,9 +210,18 @@ nsDOMAttributeMap::GetSupportedNames(unsigned aFlags,
nsString qualifiedName;
name->GetQualifiedName(qualifiedName);
if (lowercaseNamesOnly &&
nsContentUtils::StringContainsASCIIUpper(qualifiedName)) {
continue;
}
// Omit duplicates. We only need to do this check if we've seen a non-atom
// name, because that's the only way we can have two identical qualified
// names.
if (seenNonAtomName && aNames.Contains(qualifiedName)) {
continue;
}
aNames.AppendElement(qualifiedName);
}
}

View File

@ -2112,6 +2112,7 @@ GK_ATOM(baseURIProperty, "baseURIProperty")
GK_ATOM(lockedStyleStates, "lockedStyleStates")
GK_ATOM(apzCallbackTransform, "apzCallbackTransform")
GK_ATOM(restylableAnonymousNode, "restylableAnonymousNode")
GK_ATOM(paintRequestTime, "PaintRequestTime")
// Languages for lang-specific transforms
GK_ATOM(Japanese, "ja")

View File

@ -10552,7 +10552,7 @@ nsGlobalWindow::ShowSlowScriptDialog()
}
// Check if we should offer the option to debug
JS::AutoFilename filename;
JS::UniqueChars filename;
unsigned lineno;
bool hasFrame = JS::DescribeScriptedCaller(cx, &filename, &lineno);

View File

@ -37,7 +37,7 @@ bool
nsJSUtils::GetCallingLocation(JSContext* aContext, nsACString& aFilename,
uint32_t* aLineno, uint32_t* aColumn)
{
JS::AutoFilename filename;
JS::UniqueChars filename;
if (!JS::DescribeScriptedCaller(aContext, &filename, aLineno, aColumn)) {
return false;
}
@ -50,7 +50,7 @@ bool
nsJSUtils::GetCallingLocation(JSContext* aContext, nsAString& aFilename,
uint32_t* aLineno, uint32_t* aColumn)
{
JS::AutoFilename filename;
JS::UniqueChars filename;
if (!JS::DescribeScriptedCaller(aContext, &filename, aLineno, aColumn)) {
return false;
}

View File

@ -705,8 +705,7 @@ nsObjectLoadingContent::UnbindFromTree(bool aDeep, bool aNullParent)
}
nsObjectLoadingContent::nsObjectLoadingContent()
: mRewrittenYoutubeEmbed(false)
, mType(eType_Loading)
: mType(eType_Loading)
, mFallbackType(eFallbackAlternate)
, mRunID(0)
, mHasRunID(false)
@ -1787,7 +1786,6 @@ nsObjectLoadingContent::UpdateObjectParameters(bool aJavaURI)
NS_NOTREACHED("Unrecognized plugin-loading tag");
}
mRewrittenYoutubeEmbed = false;
// Note that the baseURI changing could affect the newURI, even if uriStr did
// not change.
if (!uriStr.IsEmpty()) {
@ -1804,7 +1802,6 @@ nsObjectLoadingContent::UpdateObjectParameters(bool aJavaURI)
uriStr,
thisContent->OwnerDoc(),
newBaseURI);
mRewrittenYoutubeEmbed = true;
newMime = NS_LITERAL_CSTRING("text/html");
}
@ -2616,8 +2613,7 @@ nsObjectLoadingContent::GetCapabilities() const
{
return eSupportImages |
eSupportPlugins |
eSupportDocuments |
eSupportSVG;
eSupportDocuments;
}
void
@ -2772,10 +2768,7 @@ nsObjectLoadingContent::GetTypeOfContent(const nsCString& aMIMEType)
return eType_Document;
}
// SVGs load as documents, but are their own capability
bool isSVG = aMIMEType.LowerCaseEqualsLiteral("image/svg+xml");
Capabilities supportType = isSVG ? eSupportSVG : eSupportDocuments;
if ((caps & supportType) && IsSupportedDocument(aMIMEType)) {
if ((caps & eSupportDocuments) && IsSupportedDocument(aMIMEType)) {
return eType_Document;
}

View File

@ -287,15 +287,14 @@ class nsObjectLoadingContent : public nsImageLoadingContent
eSupportDocuments = 1u << 2, // Documents are supported
// (nsIDocumentLoaderFactory)
// This flag always includes SVG
eSupportSVG = 1u << 3, // SVG is supported (image/svg+xml)
eSupportClassID = 1u << 4, // The classid attribute is supported
eSupportClassID = 1u << 3, // The classid attribute is supported
// If possible to get a *plugin* type from the type attribute *or* file
// extension, we can use that type and begin loading the plugin before
// opening a channel.
// A side effect of this is if the channel fails, the plugin is still
// running.
eAllowPluginSkipChannel = 1u << 5
eAllowPluginSkipChannel = 1u << 4
};
/**
@ -331,12 +330,6 @@ class nsObjectLoadingContent : public nsImageLoadingContent
*/
virtual nsContentPolicyType GetContentPolicyType() const = 0;
// True if object represents an object/embed tag pointing to a flash embed
// for a youtube video. When possible (see IsRewritableYoutubeEmbed function
// comments for details), we change these to try to load HTML5 versions of
// videos.
bool mRewrittenYoutubeEmbed : 1;
private:
// Object parameter changes returned by UpdateObjectParameters

View File

@ -4,6 +4,8 @@
webidl_base := $(topsrcdir)/dom/webidl
ifdef COMPILE_ENVIRONMENT
# Generated by moz.build
include webidlsrcs.mk
@ -54,6 +56,8 @@ codegen.pp: $(codegen_dependencies)
compiletests:
$(call SUBMAKE,libs,test)
endif
GARBAGE += \
codegen.pp \
codegen.json \

View File

@ -37,7 +37,7 @@ const int32_t kFirstShippedSchemaVersion = 15;
namespace {
// Update this whenever the DB schema is changed.
const int32_t kLatestSchemaVersion = 17;
const int32_t kLatestSchemaVersion = 18;
// ---------
// The following constants define the SQL schema. These are defined in the
@ -204,8 +204,7 @@ static_assert(int(RequestCache::Default) == 0 &&
int(RequestCache::Reload) == 2 &&
int(RequestCache::No_cache) == 3 &&
int(RequestCache::Force_cache) == 4 &&
int(RequestCache::Only_if_cached) == 5 &&
int(RequestCache::EndGuard_) == 6,
int(RequestCache::EndGuard_) == 5,
"RequestCache values are as expected");
static_assert(int(RequestRedirect::Follow) == 0 &&
int(RequestRedirect::Error) == 1 &&
@ -2411,11 +2410,13 @@ struct Migration
// the version by a single increment. Don't skip versions.
nsresult MigrateFrom15To16(mozIStorageConnection* aConn);
nsresult MigrateFrom16To17(mozIStorageConnection* aConn);
nsresult MigrateFrom17To18(mozIStorageConnection* aConn);
// Configure migration functions to run for the given starting version.
Migration sMigrationList[] = {
Migration(15, MigrateFrom15To16),
Migration(16, MigrateFrom16To17),
Migration(17, MigrateFrom17To18),
};
uint32_t sMigrationListLength = sizeof(sMigrationList) / sizeof(Migration);
@ -2653,6 +2654,37 @@ MigrateFrom16To17(mozIStorageConnection* aConn)
return rv;
}
nsresult
MigrateFrom17To18(mozIStorageConnection* aConn)
{
MOZ_ASSERT(!NS_IsMainThread());
MOZ_ASSERT(aConn);
mozStorageTransaction trans(aConn, true,
mozIStorageConnection::TRANSACTION_IMMEDIATE);
// This migration is needed in order to remove "only-if-cached" RequestCache
// values from the database. This enum value was removed from the spec in
// https://github.com/whatwg/fetch/issues/39 but we unfortunately happily
// accepted this value in the Request constructor.
//
// There is no good value to upgrade this to, so we just stick to "default".
static_assert(int(RequestCache::Default) == 0,
"This is where the 0 below comes from!");
nsresult rv = aConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"UPDATE entries SET request_cache = 0 "
"WHERE request_cache = 5;"
));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = aConn->SetSchemaVersion(18);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
return rv;
}
} // anonymous namespace
} // namespace db

View File

@ -18,6 +18,9 @@ var sts = Cc['@mozilla.org/network/stream-transport-service;1']
var hash = Cc['@mozilla.org/security/hash;1']
.createInstance(Ci.nsICryptoHash);
var prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
prefs.setBoolPref("dom.requestcache.enabled", true);
// Expose Cache and Fetch symbols on the global
Cu.importGlobalProperties(['caches', 'fetch']);

Binary file not shown.

View File

@ -20,6 +20,7 @@ function run_test() {
requestList.forEach(function(request) {
ok(request, 'each request in list should be non-null');
ok(request.redirect === 'follow', 'request.redirect should default to "follow"');
ok(request.cache === 'default', 'request.cache should have been updated to "default"' + request.cache);
});
return Promise.all(requestList.map(function(request) {
return cache.match(request);

View File

@ -449,6 +449,9 @@ const kEventConstructors = {
return new RTCPeerConnectionIceEvent(aName, aProps);
},
},
RTCTrackEvent: {
// Difficult to test required arguments.
},
ScrollAreaEvent: { create: function (aName, aProps) {
var e = document.createEvent("scrollareaevent");
e.initScrollAreaEvent(aName, aProps.bubbles, aProps.cancelable,

View File

@ -343,7 +343,7 @@ HTMLSharedObjectElement::GetCapabilities() const
{
uint32_t capabilities = eSupportPlugins | eAllowPluginSkipChannel;
if (mNodeInfo->Equals(nsGkAtoms::embed)) {
capabilities |= eSupportSVG | eSupportImages | eSupportDocuments;
capabilities |= eSupportImages | eSupportDocuments;
}
return capabilities;

View File

@ -121,6 +121,12 @@ function checkInvalidPattern(element, completeCheck)
}
}
function checkSyntaxError(element)
{
ok(!element.validity.patternMismatch,
"On SyntaxError, element should not suffer");
}
function checkPatternValidity(element)
{
element.pattern = "foo";
@ -165,17 +171,6 @@ function checkPatternValidity(element)
element.value = "foo";
checkInvalidPattern(element);
// We need '\\\\' because '\\' will produce '\\' and we want to escape the '\'
// for the regexp.
element.pattern = "foo\\\\bar";
element.value = "foo\\bar";
checkValidPattern(element);
// The same way, we want to escape the ' in the pattern.
element.pattern = "foo\\'bar";
element.value = "foo'bar";
checkValidPattern(element);
// Check for 'i' flag disabled. Should be case sensitive.
element.value = "Foo";
checkInvalidPattern(element);
@ -183,6 +178,20 @@ function checkPatternValidity(element)
// We can't check for the 'g' flag because we only test, we don't execute.
// We can't check for the 'm' flag because .value shouldn't contain line breaks.
// We need '\\\\' because '\\' will produce '\\' and we want to escape the '\'
// for the regexp.
element.pattern = "foo\\\\bar";
element.value = "foo\\bar";
checkValidPattern(element);
// We may want to escape the ' in the pattern, but this is a SyntaxError
// when unicode flag is set.
element.pattern = "foo\\'bar";
element.value = "foo'bar";
checkSyntaxError(element);
element.value = "baz";
checkSyntaxError(element);
// We should check the pattern attribute do not pollute |RegExp.lastParen|.
is(RegExp.lastParen, "", "RegExp.lastParen should be the empty string");
@ -254,6 +263,33 @@ function checkPatternValidity(element)
element.removeAttribute('pattern');
checkValidPattern(element, true);
// Unicode pattern
for (var pattern of ["\\u{1F438}{2}", "\u{1F438}{2}",
"\\uD83D\\uDC38{2}", "\uD83D\uDC38{2}",
"\u{D83D}\u{DC38}{2}"]) {
element.pattern = pattern;
element.value = "\u{1F438}\u{1F438}";
checkValidPattern(element);
element.value = "\uD83D\uDC38\uD83D\uDC38";
checkValidPattern(element);
element.value = "\uD83D\uDC38\uDC38";
checkInvalidPattern(element);
}
element.pattern = "\\u{D83D}\\u{DC38}{2}";
element.value = "\u{1F438}\u{1F438}";
checkInvalidPattern(element);
element.value = "\uD83D\uDC38\uD83D\uDC38";
checkInvalidPattern(element);
element.value = "\uD83D\uDC38\uDC38";
checkInvalidPattern(element);
}
var input = document.getElementById('i');

View File

@ -57,7 +57,8 @@ interface nsIServiceWorkerRegistrationInfo : nsISupports
// Allows to get the related nsIServiceWorkerInfo for a given
// nsIWorkerDebugger. Over time we shouldn't need this anymore,
// and instead always control then nsIWorkerDebugger from
// nsIServiceWorkerInfo and not the other way around.
// nsIServiceWorkerInfo and not the other way around. Returns
// null if the service worker is no longer registered.
nsIServiceWorkerInfo getWorkerByID(in unsigned long long aID);
void addListener(in nsIServiceWorkerRegistrationInfoListener listener);

View File

@ -189,3 +189,4 @@ InterceptionRejectedResponseWithURL=Failed to load '%1$S'. A ServiceWorker passe
# LOCALIZATION NOTE: Do not translate "ServiceWorker", "promise", "FetchEvent.respondWith()", or "Response". %1$S is a URL. %2$S is an error string.
InterceptedNonResponseWithURL=Failed to load '%1$S'. A ServiceWorker passed a promise to FetchEvent.respondWith() that resolved with non-Response value '%2$S'.
ExecCommandCutCopyDeniedNotInputDriven=document.execCommand('cut'/'copy') was denied because it was not called from inside a short running user-generated event handler.
PatternAttributeCompileFailure=Unable to check <input pattern='%S'> because the pattern is not a valid regexp: %S

View File

@ -405,8 +405,9 @@ RTCPeerConnection.prototype = {
"InvalidStateError");
}
this.makeGetterSetterEH("onaddstream");
this.makeGetterSetterEH("onaddtrack");
this.makeGetterSetterEH("ontrack");
this.makeLegacyGetterSetterEH("onaddstream", "Use peerConnection.ontrack instead.");
this.makeLegacyGetterSetterEH("onaddtrack", "Use peerConnection.ontrack instead.");
this.makeGetterSetterEH("onicecandidate");
this.makeGetterSetterEH("onnegotiationneeded");
this.makeGetterSetterEH("onsignalingstatechange");
@ -663,6 +664,18 @@ RTCPeerConnection.prototype = {
});
},
makeLegacyGetterSetterEH: function(name, msg) {
Object.defineProperty(this, name,
{
get:function() { return this.getEH(name); },
set:function(h) {
this.logWarning(name + " is deprecated! " + msg,
null, 0);
return this.setEH(name, h);
}
});
},
_addIdentityAssertion: function(sdpPromise, origin) {
if (!this._localIdp.enabled) {
return sdpPromise;
@ -1353,15 +1366,16 @@ PeerConnectionObserver.prototype = {
// STUN requests.
handleIceConnectionStateChange: function(iceConnectionState) {
if (this._dompc.iceConnectionState === 'new') {
let pc = this._dompc;
if (pc.iceConnectionState === 'new') {
var checking_histogram = Services.telemetry.getHistogramById("WEBRTC_ICE_CHECKING_RATE");
if (iceConnectionState === 'checking') {
checking_histogram.add(true);
} else if (iceConnectionState === 'failed') {
checking_histogram.add(false);
}
} else if (this._dompc.iceConnectionState === 'checking') {
var success_histogram = Services.telemetry.getHistogramById(this._dompc._isLoop ?
} else if (pc.iceConnectionState === 'checking') {
var success_histogram = Services.telemetry.getHistogramById(pc._isLoop ?
"LOOP_ICE_SUCCESS_RATE" : "WEBRTC_ICE_SUCCESS_RATE");
if (iceConnectionState === 'completed' ||
iceConnectionState === 'connected') {
@ -1372,10 +1386,10 @@ PeerConnectionObserver.prototype = {
}
if (iceConnectionState === 'failed') {
this._dompc.logError("ICE failed, see about:webrtc for more details", null, 0);
pc.logError("ICE failed, see about:webrtc for more details", null, 0);
}
this._dompc.changeIceConnectionState(iceConnectionState);
pc.changeIceConnectionState(iceConnectionState);
},
// This method is responsible for updating iceGatheringState. This
@ -1430,11 +1444,11 @@ PeerConnectionObserver.prototype = {
},
onGetStatsSuccess: function(dict) {
let chromeobj = new RTCStatsReport(this._dompc._win, dict);
let webidlobj = this._dompc._win.RTCStatsReport._create(this._dompc._win,
chromeobj);
let pc = this._dompc;
let chromeobj = new RTCStatsReport(pc._win, dict);
let webidlobj = pc._win.RTCStatsReport._create(pc._win, chromeobj);
chromeobj.makeStatsPublic();
this._dompc._onGetStatsSuccess(webidlobj);
pc._onGetStatsSuccess(webidlobj);
},
onGetStatsError: function(code, message) {
@ -1447,20 +1461,34 @@ PeerConnectionObserver.prototype = {
this.dispatchEvent(ev);
},
onRemoveStream: function(stream, type) {
onRemoveStream: function(stream) {
this.dispatchEvent(new this._dompc._win.MediaStreamEvent("removestream",
{ stream: stream }));
},
onAddTrack: function(track) {
let ev = new this._dompc._win.MediaStreamTrackEvent("addtrack",
{ track: track });
onAddTrack: function(track, streams) {
let pc = this._dompc;
let receiver = pc._win.RTCRtpReceiver._create(pc._win,
new RTCRtpReceiver(this,
track));
pc._receivers.push(receiver);
let ev = new pc._win.RTCTrackEvent("track",
{ receiver: receiver,
track: track,
streams: streams });
this.dispatchEvent(ev);
// Fire legacy event as well for a little bit.
ev = new pc._win.MediaStreamTrackEvent("addtrack", { track: track });
this.dispatchEvent(ev);
},
onRemoveTrack: function(track, type) {
this.dispatchEvent(new this._dompc._win.MediaStreamTrackEvent("removetrack",
{ track: track }));
onRemoveTrack: function(track) {
let pc = this._dompc;
let i = pc._receivers.findIndex(receiver => receiver.track == track);
if (i >= 0) {
pc._receivers.splice(i, 1);
}
},
onReplaceTrackSuccess: function() {
@ -1534,7 +1562,7 @@ RTCRtpSender.prototype = {
};
function RTCRtpReceiver(pc, track) {
this.pc = pc;
this._pc = pc;
this.track = track;
}
RTCRtpReceiver.prototype = {

View File

@ -19,6 +19,12 @@
#include <ui/Fence.h>
#endif
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
#include <gui/Surface.h>
#else
#include <gui/SurfaceTextureClient.h>
#endif
#include "mozilla/layers/GrallocTextureClient.h"
#include "mozilla/layers/TextureClient.h"
#include "mozilla/Preferences.h"
@ -231,11 +237,11 @@ OmxDecoder::AllocateMediaResources()
#endif
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 21
mNativeWindowClient = new GonkNativeWindowClient(producer);
mNativeWindowClient = new Surface(producer);
#elif defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
mNativeWindowClient = new GonkNativeWindowClient(mNativeWindow->getBufferQueue());
mNativeWindowClient = new Surface(mNativeWindow->getBufferQueue());
#else
mNativeWindowClient = new GonkNativeWindowClient(mNativeWindow);
mNativeWindowClient = new SurfaceTextureClient(mNativeWindow);
#endif
// Experience with OMX codecs is that only the HW decoders are

View File

@ -6,7 +6,6 @@
#include <stagefright/MediaExtractor.h>
#include "GonkNativeWindow.h"
#include "GonkNativeWindowClient.h"
#include "mozilla/layers/FenceUtils.h"
#include "MP3FrameParser.h"
#include "MPAPI.h"
@ -42,7 +41,8 @@ class OmxDecoder : public RefBase {
AbstractMediaDecoder *mDecoder;
sp<GonkNativeWindow> mNativeWindow;
sp<GonkNativeWindowClient> mNativeWindowClient;
sp<ANativeWindow> mNativeWindowClient;
sp<MediaSource> mVideoTrack;
sp<OMXCodecProxy> mVideoSource;
sp<MediaSource> mAudioOffloadTrack;

View File

@ -154,6 +154,12 @@ VorbisDataDecoder::DoDecode(MediaRawData* aSample)
MOZ_ASSERT(mPacketCount >= 3);
if (!mLastFrameTime || mLastFrameTime.ref() != aSample->mTime) {
// We are starting a new block.
mFrames = 0;
mLastFrameTime = Some(aSample->mTime);
}
ogg_packet pkt = InitVorbisPacket(aData, aLength, false, false, -1, mPacketCount++);
bool first_packet = mPacketCount == 4;
@ -197,7 +203,7 @@ VorbisDataDecoder::DoDecode(MediaRawData* aSample)
NS_WARNING("Int overflow converting WebM audio duration");
return -1;
}
CheckedInt64 total_duration = FramesToUsecs(aTotalFrames,
CheckedInt64 total_duration = FramesToUsecs(mFrames,
mVorbisDsp.vi->rate);
if (!total_duration.isValid()) {
NS_WARNING("Int overflow converting WebM audio total_duration");
@ -218,7 +224,7 @@ VorbisDataDecoder::DoDecode(MediaRawData* aSample)
Move(buffer),
mVorbisDsp.vi->channels,
mVorbisDsp.vi->rate));
mFrames += aTotalFrames;
mFrames += frames;
if (vorbis_synthesis_read(&mVorbisDsp, frames) != 0) {
return -1;
}
@ -252,7 +258,7 @@ VorbisDataDecoder::Flush()
// aren't fatal and it fails when ResetDecode is called at a
// time when no vorbis data has been read.
vorbis_synthesis_restart(&mVorbisDsp);
mFrames = 0;
mLastFrameTime.reset();
return NS_OK;
}

View File

@ -7,6 +7,7 @@
#define VorbisDecoder_h_
#include "PlatformDecoderModule.h"
#include "mozilla/Maybe.h"
#ifdef MOZ_TREMOR
#include "tremor/ivorbiscodec.h"
@ -52,6 +53,7 @@ private:
int64_t mPacketCount;
int64_t mFrames;
Maybe<int64_t> mLastFrameTime;
};
} // namespace mozilla

View File

@ -9,6 +9,9 @@
#include "FFmpegLog.h"
#include "mozilla/Preferences.h"
#include "mozilla/Types.h"
#include "nsIFile.h"
#include "nsXPCOMPrivate.h" // for XUL_DLL
#include "prmem.h"
#include "prlink.h"
#if defined(XP_WIN)
@ -98,14 +101,43 @@ FFmpegRuntimeLinker::Link()
FFMPEG_LOG(" ]\n");
#ifdef MOZ_FFVPX
// We retrieve the path of the XUL library as this is where mozavcodec and
// mozavutil libs are located.
char* path =
PR_GetLibraryFilePathname(XUL_DLL, (PRFuncPtr)&FFmpegRuntimeLinker::Link);
if (!path) {
return false;
}
nsCOMPtr<nsIFile> xulFile = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID);
if (!xulFile ||
NS_FAILED(xulFile->InitWithNativePath(nsDependentCString(path)))) {
PR_Free(path);
return false;
}
PR_Free(path);
nsCOMPtr<nsIFile> rootDir;
if (NS_FAILED(xulFile->GetParent(getter_AddRefs(rootDir))) || !rootDir) {
return false;
}
nsAutoCString rootPath;
if (NS_FAILED(rootDir->GetNativePath(rootPath))) {
return false;
}
char* libname = NULL;
/* Get the platform-dependent library name of the module */
libname = PR_GetLibraryName(nullptr, "mozavutil");
MOZ_ASSERT(libname);
libname = PR_GetLibraryName(rootPath.get(), "mozavutil");
if (!libname) {
return false;
}
sLinkedUtilLib = MozAVLink(libname);
PR_FreeLibraryName(libname);
libname = PR_GetLibraryName(nullptr, "mozavcodec");
MOZ_ASSERT(libname);
libname = PR_GetLibraryName(rootPath.get(), "mozavcodec");
if (!libname) {
Unlink();
return false;
}
sLinkedLib = MozAVLink(libname);
PR_FreeLibraryName(libname);
if (sLinkedLib && sLinkedUtilLib) {

View File

@ -39,6 +39,7 @@ if CONFIG['MOZ_EME']:
DIRS += ['agnostic/eme']
if CONFIG['MOZ_FFMPEG']:
LOCAL_INCLUDES += ['/xpcom/build']
EXPORTS += [
'ffmpeg/FFmpegRuntimeLinker.h',
]

View File

@ -25,7 +25,7 @@ extern mozilla::LogModule* GetPDMLog();
#undef LOG
#endif
#define LOG(arg, ...) MOZ_LOG(GetPDMLog(), mozilla::LogLevel::Debug, ("GonkOmxPlatformLayer:: " arg, ##__VA_ARGS__))
#define LOG(arg, ...) MOZ_LOG(GetPDMLog(), mozilla::LogLevel::Debug, ("GonkOmxPlatformLayer(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
#define CHECK_ERR(err) \
if (err != OK) { \
@ -314,7 +314,7 @@ GonkBufferData::GetPlatformMediaData()
false,
0,
info.mImage);
LOG("GetMediaData: %p, disp width %d, height %d, pic width %d, height %d, time %ld",
LOG("%p, disp width %d, height %d, pic width %d, height %d, time %ld",
this, info.mDisplay.width, info.mDisplay.height,
info.mImage.width, info.mImage.height, mBuffer->nTimeStamp);
@ -324,7 +324,9 @@ GonkBufferData::GetPlatformMediaData()
->Then(mGonkPlatformLayer->GetTaskQueue(), __func__,
[self] () {
// Waiting for texture to be freed.
self->mTextureClientRecycleHandler->GetTextureClient()->WaitForBufferOwnership();
if (self->mTextureClientRecycleHandler) {
self->mTextureClientRecycleHandler->GetTextureClient()->WaitForBufferOwnership();
}
self->mPromise.ResolveIfExists(self, __func__);
},
[self] () {

View File

@ -13,9 +13,17 @@ extern mozilla::LogModule* GetPDMLog();
#ifdef LOG
#undef LOG
#undef LOGL
#endif
#define LOG(arg, ...) MOZ_LOG(GetPDMLog(), mozilla::LogLevel::Debug, ("OmxDataDecoder::%s: " arg, __func__, ##__VA_ARGS__))
#define LOG(arg, ...) MOZ_LOG(GetPDMLog(), mozilla::LogLevel::Debug, ("OmxDataDecoder(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
#define LOGL(arg, ...) \
{ \
void* p = self; \
MOZ_LOG(GetPDMLog(), mozilla::LogLevel::Debug, \
("OmxDataDecoder(%p)::%s: " arg, p, __func__, ##__VA_ARGS__)); \
}
#define CHECK_OMX_ERR(err) \
if (err != OMX_ErrorNone) { \
@ -117,7 +125,7 @@ OmxDataDecoder::OmxDataDecoder(const TrackInfo& aTrackInfo,
, mPortSettingsChanged(-1, "OmxDataDecoder::mPortSettingsChanged")
, mCallback(aCallback)
{
LOG("(%p)", this);
LOG("");
mOmxLayer = new OmxPromiseLayer(mOmxTaskQueue, this, aImageContainer);
nsCOMPtr<nsIRunnable> r =
@ -127,7 +135,7 @@ OmxDataDecoder::OmxDataDecoder(const TrackInfo& aTrackInfo,
OmxDataDecoder::~OmxDataDecoder()
{
LOG("(%p)", this);
LOG("");
}
void
@ -140,21 +148,27 @@ OmxDataDecoder::InitializationTask()
void
OmxDataDecoder::EndOfStream()
{
LOG("(%p)", this);
LOG("");
MOZ_ASSERT(mOmxTaskQueue->IsCurrentThreadIn());
mFlushing = true;
RefPtr<OmxDataDecoder> self = this;
nsCOMPtr<nsIRunnable> r =
NS_NewRunnableFunction([self] () {
self->mCallback->DrainComplete();
});
mReaderTaskQueue->Dispatch(r.forget());
mOmxLayer->SendCommand(OMX_CommandFlush, OMX_ALL, nullptr)
->Then(mReaderTaskQueue, __func__,
[self] () {
self->mFlushing = false;
self->mCallback->DrainComplete();
},
[self] () {
self->mFlushing = false;
self->mCallback->DrainComplete();
});
}
RefPtr<MediaDataDecoder::InitPromise>
OmxDataDecoder::Init()
{
LOG("(%p)", this);
LOG("");
mReaderTaskQueue = AbstractThread::GetCurrent()->AsTaskQueue();
MOZ_ASSERT(mReaderTaskQueue);
@ -181,7 +195,7 @@ OmxDataDecoder::Init()
nsresult
OmxDataDecoder::Input(MediaRawData* aSample)
{
LOG("(%p) sample %p", this, aSample);
LOG("sample %p", aSample);
MOZ_ASSERT(mInitPromise.IsEmpty());
RefPtr<OmxDataDecoder> self = this;
@ -205,7 +219,7 @@ OmxDataDecoder::Input(MediaRawData* aSample)
nsresult
OmxDataDecoder::Flush()
{
LOG("(%p)", this);
LOG("");
mFlushing = true;
@ -227,7 +241,7 @@ OmxDataDecoder::Flush()
nsresult
OmxDataDecoder::Drain()
{
LOG("(%p)", this);
LOG("");
nsCOMPtr<nsIRunnable> r =
NS_NewRunnableMethod(this, &OmxDataDecoder::SendEosBuffer);
@ -239,7 +253,7 @@ OmxDataDecoder::Drain()
nsresult
OmxDataDecoder::Shutdown()
{
LOG("(%p)", this);
LOG("");
mShuttingDown = true;
@ -266,7 +280,7 @@ OmxDataDecoder::Shutdown()
void
OmxDataDecoder::DoAsyncShutdown()
{
LOG("(%p)", this);
LOG("");
MOZ_ASSERT(mOmxTaskQueue->IsCurrentThreadIn());
MOZ_ASSERT(!mFlushing);
@ -278,7 +292,7 @@ OmxDataDecoder::DoAsyncShutdown()
mOmxLayer->SendCommand(OMX_CommandFlush, OMX_ALL, nullptr)
->Then(mOmxTaskQueue, __func__,
[self] () -> RefPtr<OmxCommandPromise> {
LOG("DoAsyncShutdown: flush complete");
LOGL("DoAsyncShutdown: flush complete");
return self->mOmxLayer->SendCommand(OMX_CommandStateSet, OMX_StateIdle, nullptr);
},
[self] () {
@ -298,7 +312,7 @@ OmxDataDecoder::DoAsyncShutdown()
// Here the buffer promises are not resolved due to displaying
// in layer, it needs to wait before the layer returns the
// buffers.
LOG("DoAsyncShutdown: releasing buffers...");
LOGL("DoAsyncShutdown: releasing buffers...");
self->ReleaseBuffers(OMX_DirInput);
self->ReleaseBuffers(OMX_DirOutput);
@ -310,7 +324,7 @@ OmxDataDecoder::DoAsyncShutdown()
->CompletionPromise()
->Then(mOmxTaskQueue, __func__,
[self] () {
LOG("DoAsyncShutdown: OMX_StateLoaded, it is safe to shutdown omx");
LOGL("DoAsyncShutdown: OMX_StateLoaded, it is safe to shutdown omx");
self->mOmxLayer->Shutdown();
self->mWatchManager.Shutdown();
self->mOmxLayer = nullptr;
@ -432,7 +446,7 @@ OmxDataDecoder::EmptyBufferDone(BufferData* aData)
return;
}
LOG("Call InputExhausted()");
LOGL("Call InputExhausted()");
self->mCallback->InputExhausted();
});
@ -521,7 +535,6 @@ OmxDataDecoder::FindAvailableBuffer(OMX_DIRTYPE aType)
if (buf->mStatus == BufferData::BufferStatus::FREE) {
return buf;
}
LOG("buffer is owned by %d, type %d", buf->mStatus, aType);
}
return nullptr;
@ -558,7 +571,7 @@ OmxDataDecoder::GetBuffers(OMX_DIRTYPE aType)
void
OmxDataDecoder::ResolveInitPromise(const char* aMethodName)
{
LOG("Resolved InitPromise");
LOG("called from %s", aMethodName);
RefPtr<OmxDataDecoder> self = this;
nsCOMPtr<nsIRunnable> r =
NS_NewRunnableFunction([self, aMethodName] () {
@ -906,7 +919,7 @@ OmxDataDecoder::PortSettingsChanged()
->CompletionPromise()
->Then(mOmxTaskQueue, __func__,
[self] () {
LOG("PortSettingsChanged: port settings changed complete");
LOGL("PortSettingsChanged: port settings changed complete");
// finish port setting changed.
self->mPortSettingsChanged = -1;
self->FillAndEmptyBuffers();

View File

@ -18,7 +18,7 @@ extern mozilla::LogModule* GetPDMLog();
#undef LOG
#endif
#define LOG(arg, ...) MOZ_LOG(GetPDMLog(), mozilla::LogLevel::Debug, ("OmxPromiseLayer:: " arg, ##__VA_ARGS__))
#define LOG(arg, ...) MOZ_LOG(GetPDMLog(), mozilla::LogLevel::Debug, ("OmxPromiseLayer(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
namespace mozilla {
@ -62,7 +62,7 @@ RefPtr<OmxPromiseLayer::OmxBufferPromise>
OmxPromiseLayer::FillBuffer(BufferData* aData)
{
MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
LOG("FillBuffer: buffer %p", aData->mBuffer);
LOG("buffer %p", aData->mBuffer);
RefPtr<OmxBufferPromise> p = aData->mPromise.Ensure(__func__);
@ -83,7 +83,7 @@ RefPtr<OmxPromiseLayer::OmxBufferPromise>
OmxPromiseLayer::EmptyBuffer(BufferData* aData)
{
MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
LOG("EmptyBuffer: buffer %p, size %d", aData->mBuffer, aData->mBuffer->nFilledLen);
LOG("buffer %p, size %d", aData->mBuffer, aData->mBuffer->nFilledLen);
RefPtr<OmxBufferPromise> p = aData->mPromise.Ensure(__func__);
@ -169,7 +169,7 @@ void
OmxPromiseLayer::EmptyFillBufferDone(OMX_DIRTYPE aType, BufferData* aData)
{
MOZ_ASSERT(!!aData);
LOG("EmptyFillBufferDone: type %d, buffer %p", aType, aData->mBuffer);
LOG("type %d, buffer %p", aType, aData->mBuffer);
if (aData) {
if (aType == OMX_DirOutput) {
aData->mRawData = nullptr;
@ -222,7 +222,7 @@ OmxPromiseLayer::SendCommand(OMX_COMMANDTYPE aCmd, OMX_U32 aParam1, OMX_PTR aCmd
return OmxCommandPromise::CreateAndReject(failure, __func__);
}
} else {
LOG("SendCommand: OMX_CommandFlush parameter error");
LOG("OMX_CommandFlush parameter error");
OmxCommandFailureHolder failure(OMX_ErrorNotReady, OMX_CommandFlush);
return OmxCommandPromise::CreateAndReject(failure, __func__);
}
@ -244,7 +244,7 @@ OmxPromiseLayer::SendCommand(OMX_COMMANDTYPE aCmd, OMX_U32 aParam1, OMX_PTR aCmd
} else if (aCmd == OMX_CommandPortDisable) {
p = mPortDisablePromise.Ensure(__func__);
} else {
LOG("SendCommand: error unsupport command");
LOG("error unsupport command");
MOZ_ASSERT(0);
}
@ -262,7 +262,7 @@ OmxPromiseLayer::Event(OMX_EVENTTYPE aEvent, OMX_U32 aData1, OMX_U32 aData2)
mCommandStatePromise.Resolve(OMX_CommandStateSet, __func__);
} else if (cmd == OMX_CommandFlush) {
MOZ_RELEASE_ASSERT(mFlushCommands.ElementAt(0).type == aData2);
LOG("Event: OMX_CommandFlush completed port type %d", aData2);
LOG("OMX_CommandFlush completed port type %d", aData2);
mFlushCommands.RemoveElementAt(0);
// Sending next flush command.
@ -355,7 +355,7 @@ OmxPromiseLayer::SetParameter(OMX_INDEXTYPE aParamIndex,
nsresult
OmxPromiseLayer::Shutdown()
{
LOG("Shutdown");
LOG("");
MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
MOZ_ASSERT(!GetBufferHolders(OMX_DirInput)->Length());
MOZ_ASSERT(!GetBufferHolders(OMX_DirOutput)->Length());

View File

@ -206,7 +206,10 @@ skip-if = toolkit == 'gonk' || android_version == '18'
[test_peerConnection_addDataChannel.html]
skip-if = toolkit == 'gonk' # B2G emulator seems to be so slow that DTLS cannot establish properly
[test_peerConnection_addDataChannelNoBundle.html]
skip-if = toolkit == 'gonk' # B2G emulator seems to be so slow that DTLS cannot establish properly
skip-if = toolkit == 'gonk' || (android_version == '18' && debug) # b2g(emulator seems to be so slow that DTLS cannot establish properly), android(bug 1240256, intermittent ICE failures starting w/bug 1232082, possibly from timeout)
# b2g(Bug 960442, video support for WebRTC is disabled on b2g), android(Bug 1189784, timeouts on 4.3 emulator)
[test_peerConnection_webAudio.html]
tags = webaudio webrtc
skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g (Bug 1059867)

View File

@ -1393,6 +1393,9 @@ PeerConnectionWrapper.prototype = {
var rtpStatsKey = Object.keys(stats)
.find(key => !stats[key].isRemote && stats[key].type.endsWith("boundrtp"));
ok(rtpStatsKey, "Should have RTP stats for track " + track.id);
if (!rtpStatsKey) {
return false;
}
var rtp = stats[rtpStatsKey];
var nrPackets = rtp[rtp.type == "outboundrtp" ? "packetsSent"
: "packetsReceived"];
@ -1401,21 +1404,12 @@ PeerConnectionWrapper.prototype = {
return nrPackets > 0;
};
return new Promise(resolve => {
info("Checking RTP packet flow for track " + track.id);
info("Checking RTP packet flow for track " + track.id);
var waitForFlow = () => {
this._pc.getStats(track).then(stats => {
if (hasFlow(stats)) {
ok(true, "RTP flowing for track " + track.id);
resolve();
} else {
wait(200).then(waitForFlow);
}
});
};
waitForFlow();
});
var retry = () => this._pc.getStats(track)
.then(stats => hasFlow(stats)? ok(true, "RTP flowing for track " + track.id) :
wait(200).then(retry));
return retry();
},
/**

View File

@ -15,19 +15,33 @@
var pc1 = new RTCPeerConnection();
var pc2 = new RTCPeerConnection();
var pc2_haveRemoteOffer = new Promise(resolve => pc2.onsignalingstatechange =
e => (e.target.signalingState == "have-remote-offer") && resolve());
var pc1_stable = new Promise(resolve => pc1.onsignalingstatechange =
e => (e.target.signalingState == "stable") && resolve());
var add = (pc, can, failed) => can && pc.addIceCandidate(can).catch(failed);
pc1.onicecandidate = e => add(pc2, e.candidate, generateErrorCallback());
pc2.onicecandidate = e => add(pc1, e.candidate, generateErrorCallback());
pc1.onicecandidate = e => pc2_haveRemoteOffer.then(() => !e.candidate ||
pc2.addIceCandidate(e.candidate)).catch(generateErrorCallback());
pc2.onicecandidate = e => pc1_stable.then(() => !e.candidate ||
pc1.addIceCandidate(e.candidate)).catch(generateErrorCallback());
function mustThrowWith(msg, reason, f) {
try {
f();
ok(false, msg + " must throw");
} catch (e) {
is(e.name, reason, msg + " must throw: " + e.message);
}
};
var v1, v2;
var delivered = new Promise(resolve =>
pc2.onaddstream = e => resolve(v2.srcObject = e.stream));
var delivered = new Promise(resolve => pc2.ontrack = e => {
// Test RTCTrackEvent here.
ok(e.streams.length > 0, "has streams");
ok(e.streams[0].getTracks().some(track => track == e.track), "has track");
ok(pc2.getReceivers().some(receiver => receiver == e.receiver), "has receiver");
if (e.streams[0].getTracks().length == 2) {
// Test RTCTrackEvent required args here.
mustThrowWith("RTCTrackEvent wo/required args",
"TypeError", () => new RTCTrackEvent("track", {}));
v2.srcObject = e.streams[0];
resolve();
}
});
runNetworkTest(function() {
v1 = createMediaElement('video', 'v1');
@ -37,7 +51,7 @@
is(v2.currentTime, 0, "v2.currentTime is zero at outset");
navigator.mediaDevices.getUserMedia({ video: true, audio: true })
.then(stream => pc1.addStream(v1.srcObject = stream))
.then(stream => (v1.srcObject = stream).getTracks().forEach(t => pc1.addTrack(t, stream)))
.then(() => pc1.createOffer({})) // check that createOffer accepts arg.
.then(offer => pc1.setLocalDescription(offer))
.then(() => pc2.setRemoteDescription(pc1.localDescription))

View File

@ -19,6 +19,13 @@
.some(sn => sn.track == t))) // that's being sent over |pc|.
}
function allRemoteStreamsHaveReceiver(pc) {
return pc.getRemoteStreams()
.every(s => s.getTracks() // Every remote stream,
.some(t => pc.getReceivers() // should have some track,
.some(sn => sn.track == t))) // that's being received over |pc|.
}
function replacetest(wrapper) {
var pc = wrapper._pc;
var oldSenderCount = pc.getSenders().length;
@ -26,7 +33,9 @@
var oldTrack = sender.track;
ok(sender, "We have a sender for video");
ok(allLocalStreamsHaveSender(pc),
"Shouldn't have any streams without a corresponding sender");
"Shouldn't have any local streams without a corresponding sender");
ok(allRemoteStreamsHaveReceiver(pc),
"Shouldn't have any remote streams without a corresponding receiver");
var newTrack;
var audiotrack;

View File

@ -77,7 +77,7 @@ PermissionSettings.prototype = {
set: function set(aPermName, aPermValue, aManifestURL, aOrigin,
aBrowserFlag) {
debug("Set called with: " + aPermName + ", " + aManifestURL + ", " +
aOrigin + ", " + aPermValue + ", " + aBrowserFlag);
aOrigin + ", " + aPermValue + ", " + aBrowserFlag);
let currentPermValue = this.get(aPermName, aManifestURL, aOrigin,
aBrowserFlag);
let action;

View File

@ -23,7 +23,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1112040
/** Test for Bug 1112040 **/
SimpleTest.runTestExpectingConsoleMessages(
function() { $('i').value = "42"; },
[{ errorMessage: "SyntaxError: nothing to repeat" }]
[{ errorMessage: /nothing to repeat/ }]
);
</script>

View File

@ -999,6 +999,8 @@ var interfaceNamesInGlobalScope =
"RTCSessionDescription",
// IMPORTANT: Do not change this list without review from a DOM peer!
"RTCStatsReport",
// IMPORTANT: Do not change this list without review from a DOM peer!
"RTCTrackEvent",
// IMPORTANT: Do not change this list without review from a DOM peer!
"Screen",
// IMPORTANT: Do not change this list without review from a DOM peer!

View File

@ -42,6 +42,6 @@ interface PeerConnectionObserver
/* Changes to MediaStreamTracks */
void onAddStream(MediaStream stream);
void onRemoveStream(MediaStream stream);
void onAddTrack(MediaStreamTrack track);
void onAddTrack(MediaStreamTrack track, sequence<MediaStream> streams);
void onRemoveTrack(MediaStreamTrack track);
};

View File

@ -141,8 +141,9 @@ interface RTCPeerConnection : EventTarget {
attribute EventHandler onnegotiationneeded;
attribute EventHandler onicecandidate;
attribute EventHandler onsignalingstatechange;
attribute EventHandler onaddstream;
attribute EventHandler onaddtrack; // replaces onaddstream; see AddTrackEvent
attribute EventHandler onaddstream; // obsolete
attribute EventHandler onaddtrack; // obsolete
attribute EventHandler ontrack; // replaces onaddtrack and onaddstream.
attribute EventHandler onremovestream;
attribute EventHandler oniceconnectionstatechange;

View File

@ -0,0 +1,27 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* The origin of this IDL file is
* http://w3c.github.io/webrtc-pc/#idl-def-RTCTrackEvent
*/
dictionary RTCTrackEventInit : EventInit {
required RTCRtpReceiver receiver;
required MediaStreamTrack track;
sequence<MediaStream> streams = [];
};
[Pref="media.peerconnection.enabled",
Constructor(DOMString type, RTCTrackEventInit eventInitDict)]
interface RTCTrackEvent : Event {
readonly attribute RTCRtpReceiver receiver;
readonly attribute MediaStreamTrack track;
// TODO: Use FrozenArray once available. (Bug 1236777)
// readonly attribute FrozenArray<MediaStream> streams;
[Frozen, Cached, Pure]
readonly attribute sequence<MediaStream> streams; // workaround
};

View File

@ -57,5 +57,5 @@ enum RequestContext {
enum RequestMode { "same-origin", "no-cors", "cors" };
enum RequestCredentials { "omit", "same-origin", "include" };
enum RequestCache { "default", "no-store", "reload", "no-cache", "force-cache", "only-if-cached" };
enum RequestCache { "default", "no-store", "reload", "no-cache", "force-cache" };
enum RequestRedirect { "follow", "error", "manual" };

View File

@ -837,6 +837,7 @@ if CONFIG['MOZ_WEBRTC']:
'MediaStreamTrackEvent.webidl',
'RTCDataChannelEvent.webidl',
'RTCPeerConnectionIceEvent.webidl',
'RTCTrackEvent.webidl',
]
if CONFIG['MOZ_WEBSPEECH']:

View File

@ -643,7 +643,7 @@ ContentSecurityPolicyAllows(JSContext* aCx)
nsString fileName;
uint32_t lineNum = 0;
JS::AutoFilename file;
JS::UniqueChars file;
if (JS::DescribeScriptedCaller(aCx, &file, &lineNum) && file.get()) {
fileName = NS_ConvertUTF8toUTF16(file.get());
} else {

View File

@ -508,9 +508,7 @@ ServiceWorkerRegistrationInfo::GetWorkerByID(uint64_t aID, nsIServiceWorkerInfo
MOZ_ASSERT(aResult);
RefPtr<ServiceWorkerInfo> info = GetServiceWorkerInfoById(aID);
if (NS_WARN_IF(!info)) {
return NS_ERROR_FAILURE;
}
// It is ok to return null for a missing service worker info.
info.forget(aResult);
return NS_OK;
}

View File

@ -4298,7 +4298,7 @@ WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindow* aWindow,
// We're being created outside of a window. Need to figure out the script
// that is creating us in order for us to use relative URIs later on.
JS::AutoFilename fileName;
JS::UniqueChars fileName;
if (JS::DescribeScriptedCaller(aCx, &fileName)) {
// In most cases, fileName is URI. In a few other cases
// (e.g. xpcshell), fileName is a file path. Ideally, we would

View File

@ -899,10 +899,10 @@ void
WorkerDebuggerGlobalScope::ReportError(JSContext* aCx,
const nsAString& aMessage)
{
JS::AutoFilename afn;
JS::UniqueChars chars;
uint32_t lineno = 0;
JS::DescribeScriptedCaller(aCx, &afn, &lineno);
nsString filename(NS_ConvertUTF8toUTF16(afn.get()));
JS::DescribeScriptedCaller(aCx, &chars, &lineno);
nsString filename(NS_ConvertUTF8toUTF16(chars.get()));
mWorkerPrivate->ReportErrorToDebugger(filename, lineno, aMessage);
}

View File

@ -91,13 +91,18 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'windows':
if CONFIG['MOZ_ENABLE_SKIA']:
UNIFIED_SOURCES += [
'convolver.cpp',
]
SOURCES += [
'DrawTargetSkia.cpp',
'image_operations.cpp', # Uses _USE_MATH_DEFINES
'PathSkia.cpp',
'SourceSurfaceSkia.cpp',
]
SOURCES += [
'image_operations.cpp', # Uses _USE_MATH_DEFINES
]
if CONFIG['CLANG_CXX']:
# Suppress warnings from Skia header files.
SOURCES['DrawTargetSkia.cpp'].flags += ['-Wno-implicit-fallthrough']
SOURCES['PathSkia.cpp'].flags += ['-Wno-implicit-fallthrough']
SOURCES['SourceSurfaceSkia.cpp'].flags += ['-Wno-implicit-fallthrough']
EXPORTS.mozilla.gfx += [
'HelpersSkia.h',
'RefPtrSkia.h',
@ -143,7 +148,6 @@ UNIFIED_SOURCES += [
'DrawTargetDual.cpp',
'DrawTargetRecording.cpp',
'DrawTargetTiled.cpp',
'Factory.cpp',
'FilterNodeSoftware.cpp',
'FilterProcessing.cpp',
'FilterProcessingScalar.cpp',
@ -166,6 +170,13 @@ UNIFIED_SOURCES += [
'SourceSurfaceRawData.cpp',
]
SOURCES += [
'Factory.cpp', # Need to suppress warnings in Skia header files.
]
if CONFIG['CLANG_CXX']:
SOURCES['Factory.cpp'].flags += ['-Wno-implicit-fallthrough']
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
EXPORTS.mozilla.gfx += [
'QuartzSupport.h',

View File

@ -80,9 +80,12 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
]
if CONFIG['MOZ_ENABLE_SKIA_GPU']:
EXPORTS += ['SkiaGLGlue.h']
UNIFIED_SOURCES += [
SOURCES += [
'SkiaGLGlue.cpp',
]
if CONFIG['CLANG_CXX']:
# Suppress warnings from Skia header files.
SOURCES['SkiaGLGlue.cpp'].flags += ['-Wno-implicit-fallthrough']
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
UNIFIED_SOURCES += ['SharedSurfaceGralloc.cpp']

View File

@ -48,6 +48,7 @@ HBSOURCES = \
hb-ot-hmtx-table.hh \
hb-ot-maxp-table.hh \
hb-ot-name-table.hh \
hb-ot-os2-table.hh \
hb-ot-tag.cc \
hb-private.hh \
hb-set-private.hh \
@ -392,7 +393,14 @@ dist_check_SCRIPTS = \
check-symbols.sh \
$(NULL)
TESTS = $(dist_check_SCRIPTS)
check_PROGRAMS = \
test-ot-tag \
$(NULL)
test_ot_tag_SOURCES = hb-ot-tag.cc
test_ot_tag_CPPFLAGS = $(HBCFLAGS) -DMAIN
test_ot_tag_LDADD = libharfbuzz.la $(HBLIBS)
TESTS = $(dist_check_SCRIPTS) $(check_PROGRAMS)
TESTS_ENVIRONMENT = \
srcdir="$(srcdir)" \
MAKE="$(MAKE) $(AM_MAKEFLAGS)" \
@ -419,6 +427,7 @@ HarfBuzz_0_0_gir_CFLAGS = \
-DHB_OT_H_IN \
-DHB_GOBJECT_H \
-DHB_GOBJECT_H_IN \
-DHB_EXTERN= \
$(NULL)
HarfBuzz_0_0_gir_LIBS = \
libharfbuzz.la \

View File

@ -9,13 +9,12 @@ stat=0
test "x$HBHEADERS" = x && HBHEADERS=`cd "$srcdir"; find . -maxdepth 1 -name 'hb*.h'`
test "x$HBSOURCES" = x && HBSOURCES=`cd "$srcdir"; find . -maxdepth 1 -name 'hb-*.cc' -or -name 'hb-*.hh'`
for x in $HBHEADERS $HBSOURCES; do
test -f "$srcdir/$x" && x="$srcdir/$x"
echo "$x" | grep '[^h]$' -q && continue;
echo "$x" | grep -q '[^h]$' && continue;
xx=`echo "$x" | sed 's@.*/@@'`
tag=`echo "$xx" | tr 'a-z.-' 'A-Z_'`
lines=`grep "\<$tag\>" "$x" | wc -l | sed 's/[ ]*//g'`
lines=`grep -w "$tag" "$x" | wc -l | sed 's/[ ]*//g'`
if test "x$lines" != x3; then
echo "Ouch, header file $x does not have correct preprocessor guards"
stat=1

View File

@ -91,6 +91,7 @@ short = [{
"Visarga": 'Vs',
"Vowel": 'Vo',
"Vowel_Dependent": 'M',
"Consonant_Prefixed": 'CPrf',
"Other": 'x',
},{
"Not_Applicable": 'x',

View File

@ -119,6 +119,31 @@ typedef unsigned int hb_atomic_int_impl_t;
#define hb_atomic_ptr_impl_cmpexch(P,O,N) ( ({__machine_rw_barrier ();}), atomic_cas_ptr ((void **) (P), (void *) (O), (void *) (N)) == (void *) (O) ? true : false)
#elif !defined(HB_NO_MT) && defined(_AIX) && defined(__IBMCPP__)
#include <builtins.h>
static inline int hb_fetch_and_add(volatile int* AI, unsigned int V) {
__lwsync();
int result = __fetch_and_add(AI, V);
__isync();
return result;
}
static inline int hb_compare_and_swaplp(volatile long* P, long O, long N) {
__sync();
int result = __compare_and_swaplp (P, &O, N);
__sync();
return result;
}
typedef int hb_atomic_int_impl_t;
#define HB_ATOMIC_INT_IMPL_INIT(V) (V)
#define hb_atomic_int_impl_add(AI, V) hb_fetch_and_add (&(AI), (V))
#define hb_atomic_ptr_impl_get(P) (__sync(), (void *) *(P))
#define hb_atomic_ptr_impl_cmpexch(P,O,N) hb_compare_and_swaplp ((long*)(P), (long)(O), (long)(N))
#elif !defined(HB_NO_MT)
#define HB_ATOMIC_INT_NIL 1 /* Warn that fallback implementation is in use. */

View File

@ -64,7 +64,7 @@ typedef enum {
typedef struct hb_blob_t hb_blob_t;
hb_blob_t *
HB_EXTERN hb_blob_t *
hb_blob_create (const char *data,
unsigned int length,
hb_memory_mode_t mode,
@ -77,21 +77,21 @@ hb_blob_create (const char *data,
* modify the parent data as that data may be
* shared among multiple sub-blobs.
*/
hb_blob_t *
HB_EXTERN hb_blob_t *
hb_blob_create_sub_blob (hb_blob_t *parent,
unsigned int offset,
unsigned int length);
hb_blob_t *
HB_EXTERN hb_blob_t *
hb_blob_get_empty (void);
hb_blob_t *
HB_EXTERN hb_blob_t *
hb_blob_reference (hb_blob_t *blob);
void
HB_EXTERN void
hb_blob_destroy (hb_blob_t *blob);
hb_bool_t
HB_EXTERN hb_bool_t
hb_blob_set_user_data (hb_blob_t *blob,
hb_user_data_key_t *key,
void * data,
@ -99,25 +99,25 @@ hb_blob_set_user_data (hb_blob_t *blob,
hb_bool_t replace);
void *
HB_EXTERN void *
hb_blob_get_user_data (hb_blob_t *blob,
hb_user_data_key_t *key);
void
HB_EXTERN void
hb_blob_make_immutable (hb_blob_t *blob);
hb_bool_t
HB_EXTERN hb_bool_t
hb_blob_is_immutable (hb_blob_t *blob);
unsigned int
HB_EXTERN unsigned int
hb_blob_get_length (hb_blob_t *blob);
const char *
HB_EXTERN const char *
hb_blob_get_data (hb_blob_t *blob, unsigned int *length);
char *
HB_EXTERN char *
hb_blob_get_data_writable (hb_blob_t *blob, unsigned int *length);

View File

@ -124,6 +124,11 @@ struct hb_buffer_t {
hb_codepoint_t context[2][CONTEXT_LENGTH];
unsigned int context_len[2];
/* Debugging */
hb_buffer_message_func_t message_func;
void *message_data;
hb_destroy_func_t message_destroy;
/* Methods */
@ -174,13 +179,12 @@ struct hb_buffer_t {
if (have_output)
{
if (unlikely (out_info != info || out_len != idx)) {
if (unlikely (!make_room_for (1, 1)))
goto done;
if (unlikely (!make_room_for (1, 1))) return;
out_info[out_len] = info[idx];
}
out_len++;
}
done:
idx++;
}
@ -234,6 +238,19 @@ struct hb_buffer_t {
inline void clear_context (unsigned int side) { context_len[side] = 0; }
HB_INTERNAL void sort (unsigned int start, unsigned int end, int(*compar)(const hb_glyph_info_t *, const hb_glyph_info_t *));
inline bool messaging (void) { return unlikely (message_func); }
inline bool message (hb_font_t *font, const char *fmt, ...) HB_PRINTF_FUNC(3, 4)
{
if (!messaging ())
return true;
va_list ap;
va_start (ap, fmt);
bool ret = message_impl (font, fmt, ap);
va_end (ap);
return ret;
}
HB_INTERNAL bool message_impl (hb_font_t *font, const char *fmt, va_list ap) HB_PRINTF_FUNC(3, 0);
};

View File

@ -36,11 +36,12 @@ static const char *serialize_formats[] = {
/**
* hb_buffer_serialize_list_formats:
*
*
* Returns a list of supported buffer serialization formats.
*
* Return value: (transfer none):
* A string array of buffer serialization formats. Should not be freed.
*
* Since: 0.9.2
* Since: 0.9.7
**/
const char **
hb_buffer_serialize_list_formats (void)
@ -50,14 +51,17 @@ hb_buffer_serialize_list_formats (void)
/**
* hb_buffer_serialize_format_from_string:
* @str:
* @len:
* @str: (array length=len) (element-type uint8_t): a string to parse
* @len: length of @str, or -1 if string is %NULL terminated
*
*
* Parses a string into an #hb_buffer_serialize_format_t. Does not check if
* @str is a valid buffer serialization format, use
* hb_buffer_serialize_list_formats() to get the list of supported formats.
*
* Return value:
* The parsed #hb_buffer_serialize_format_t.
*
* Since: 0.9.2
* Since: 0.9.7
**/
hb_buffer_serialize_format_t
hb_buffer_serialize_format_from_string (const char *str, int len)
@ -68,13 +72,15 @@ hb_buffer_serialize_format_from_string (const char *str, int len)
/**
* hb_buffer_serialize_format_to_string:
* @format:
* @format: an #hb_buffer_serialize_format_t to convert.
*
*
* Converts @format to the string corresponding it, or %NULL if it is not a valid
* #hb_buffer_serialize_format_t.
*
* Return value:
* Return value: (transfer none):
* A %NULL terminated string corresponding to @format. Should not be freed.
*
* Since: 0.9.2
* Since: 0.9.7
**/
const char *
hb_buffer_serialize_format_to_string (hb_buffer_serialize_format_t format)
@ -242,24 +248,51 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
return end - start;
}
/* 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:
* @buffer: an #hb_buffer_t buffer.
* @start: the first item in @buffer to serialize.
* @end: the last item in @buffer to serialize.
* @buf: (out) (array length=buf_size) (element-type uint8_t): output string to
* write serialized buffer into.
* @buf_size: the size of @buf.
* @buf_consumed: (out) (allow-none): if not %NULL, will be set to the number of byes written into @buf.
* @font: (allow-none): the #hb_font_t used to shape this buffer, needed to
* read glyph names and extents. If %NULL, and empty font will be used.
* @format: the #hb_buffer_serialize_format_t to use for formatting the output.
* @flags: the #hb_buffer_serialize_flags_t that control what glyph properties
* to serialize.
*
*
* Serializes @buffer into a textual representation of its glyph content,
* useful for showing the contents of the buffer, for example during debugging.
* There are currently two supported serialization formats:
*
* ## text
* A human-readable, plain text format.
* The serialized glyphs will look something like:
*
* ```
* [uni0651=0@518,0+0|uni0628=0+1897]
* ```
* - The serialized glyphs are delimited with `[` and `]`.
* - Glyphs are separated with `|`
* - Each glyph starts with glyph name, or glyph index if
* #HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES flag is set. Then,
* - If #HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS is not set, `=` then #hb_glyph_info_t.cluster.
* - If #HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS is not set, the #hb_glyph_position_t in the format:
* - If both #hb_glyph_position_t.x_offset and #hb_glyph_position_t.y_offset are not 0, `@x_offset,y_offset`. Then,
* - `+x_advance`, then `,y_advance` if #hb_glyph_position_t.y_advance is not 0. Then,
* - If #HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS is set, the
* #hb_glyph_extents_t in the format
* `&lt;x_bearing,y_bearing,width,height&gt;`
*
* ## json
* TODO.
*
* Return value:
* The number of serialized items.
*
* Since: 0.9.2
* Since: 0.9.7
**/
unsigned int
hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
@ -267,8 +300,8 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
unsigned int end,
char *buf,
unsigned int buf_size,
unsigned int *buf_consumed, /* May be NULL */
hb_font_t *font, /* May be NULL */
unsigned int *buf_consumed,
hb_font_t *font,
hb_buffer_serialize_format_t format,
hb_buffer_serialize_flags_t flags)
{
@ -282,6 +315,9 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
assert ((!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID) ||
buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS);
if (!buffer->have_positions)
flags |= HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS;
if (unlikely (start == end))
return 0;
@ -355,7 +391,7 @@ parse_int (const char *pp, const char *end, int32_t *pv)
/**
* hb_buffer_deserialize_glyphs:
* @buffer: a buffer.
* @buffer: an #hb_buffer_t buffer.
* @buf: (array length=buf_len):
* @buf_len:
* @end_ptr: (out):
@ -366,7 +402,7 @@ parse_int (const char *pp, const char *end, int32_t *pv)
*
* Return value:
*
* Since: 0.9.2
* Since: 0.9.7
**/
hb_bool_t
hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,

View File

@ -35,8 +35,26 @@
#define HB_DEBUG_BUFFER (HB_DEBUG+0)
#endif
/**
* SECTION: hb-buffer
* @title: Buffers
* @short_description: Input and output buffers
* @include: hb.h
*
* Buffers serve dual role in HarfBuzz; they hold the input characters that are
* passed hb_shape(), and after shaping they hold the output glyphs.
**/
/**
* hb_segment_properties_equal:
* @a: first #hb_segment_properties_t to compare.
* @b: second #hb_segment_properties_t to compare.
*
* Checks the equality of two #hb_segment_properties_t's.
*
* Return value: (transfer full):
* %true if all properties of @a equal those of @b, false otherwise.
*
* Since: 0.9.7
**/
hb_bool_t
@ -52,6 +70,14 @@ hb_segment_properties_equal (const hb_segment_properties_t *a,
}
/**
* hb_segment_properties_hash:
* @p: #hb_segment_properties_t to hash.
*
* Creates a hash representing @p.
*
* Return value:
* A hash of @p.
*
* Since: 0.9.7
**/
unsigned int
@ -324,9 +350,7 @@ hb_buffer_t::replace_glyphs (unsigned int num_in,
unsigned int num_out,
const uint32_t *glyph_data)
{
if (unlikely (!make_room_for (num_in, num_out)))
goto done;
{
if (unlikely (!make_room_for (num_in, num_out))) return;
merge_clusters (idx, idx + num_in);
@ -339,50 +363,39 @@ hb_buffer_t::replace_glyphs (unsigned int num_in,
pinfo++;
}
out_len += num_out;
}
done:
idx += num_in;
out_len += num_out;
}
void
hb_buffer_t::output_glyph (hb_codepoint_t glyph_index)
{
if (unlikely (!make_room_for (0, 1)))
goto done;
if (unlikely (!make_room_for (0, 1))) return;
out_info[out_len] = info[idx];
out_info[out_len].codepoint = glyph_index;
out_len++;
done:
;
}
void
hb_buffer_t::output_info (const hb_glyph_info_t &glyph_info)
{
if (unlikely (!make_room_for (0, 1)))
goto done;
if (unlikely (!make_room_for (0, 1))) return;
out_info[out_len] = glyph_info;
out_len++;
done:
;
}
void
hb_buffer_t::copy_glyph (void)
{
if (unlikely (!make_room_for (0, 1)))
goto done;
if (unlikely (!make_room_for (0, 1))) return;
out_info[out_len] = info[idx];
out_len++;
done:
;
}
bool
@ -400,7 +413,7 @@ hb_buffer_t::move_to (unsigned int i)
if (out_len < i)
{
unsigned int count = i - out_len;
if (unlikely (!make_room_for (count, count))) return false; // XXX verify bailout
if (unlikely (!make_room_for (count, count))) return false;
memmove (out_info + out_len, info + idx, count * sizeof (out_info[0]));
idx += count;
@ -427,15 +440,13 @@ void
hb_buffer_t::replace_glyph (hb_codepoint_t glyph_index)
{
if (unlikely (out_info != info || out_len != idx)) {
if (unlikely (!make_room_for (1, 1)))
goto out;
if (unlikely (!make_room_for (1, 1))) return;
out_info[out_len] = info[idx];
}
out_info[out_len].codepoint = glyph_index;
out_len++;
out:
idx++;
out_len++;
}
@ -721,9 +732,14 @@ void hb_buffer_t::deallocate_var_all (void)
/**
* hb_buffer_create: (Xconstructor)
*
*
* Creates a new #hb_buffer_t with all properties to defaults.
*
* Return value: (transfer full)
* Return value: (transfer full):
* A newly allocated #hb_buffer_t with a reference count of 1. The initial
* reference count should be released with hb_buffer_destroy() when you are done
* using the #hb_buffer_t. This function never returns %NULL. If memory cannot
* be allocated, a special #hb_buffer_t object will be returned on which
* hb_buffer_allocation_successful() returns %false.
*
* Since: 0.9.2
**/
@ -778,11 +794,13 @@ hb_buffer_get_empty (void)
/**
* hb_buffer_reference: (skip)
* @buffer: a buffer.
* @buffer: an #hb_buffer_t.
*
*
* Increases the reference count on @buffer by one. This prevents @buffer from
* being destroyed until a matching call to hb_buffer_destroy() is made.
*
* Return value: (transfer full):
* The referenced #hb_buffer_t.
*
* Since: 0.9.2
**/
@ -794,9 +812,11 @@ hb_buffer_reference (hb_buffer_t *buffer)
/**
* hb_buffer_destroy: (skip)
* @buffer: a buffer.
* @buffer: an #hb_buffer_t.
*
*
* Deallocate the @buffer.
* Decreases the reference count on @buffer by one. If the result is zero, then
* @buffer and all associated resources are freed. See hb_buffer_reference().
*
* Since: 0.9.2
**/
@ -809,13 +829,15 @@ hb_buffer_destroy (hb_buffer_t *buffer)
free (buffer->info);
free (buffer->pos);
if (buffer->message_destroy)
buffer->message_destroy (buffer->message_data);
free (buffer);
}
/**
* hb_buffer_set_user_data: (skip)
* @buffer: a buffer.
* @buffer: an #hb_buffer_t.
* @key:
* @data:
* @destroy:
@ -839,7 +861,7 @@ hb_buffer_set_user_data (hb_buffer_t *buffer,
/**
* hb_buffer_get_user_data: (skip)
* @buffer: a buffer.
* @buffer: an #hb_buffer_t.
* @key:
*
*
@ -858,10 +880,11 @@ hb_buffer_get_user_data (hb_buffer_t *buffer,
/**
* hb_buffer_set_content_type:
* @buffer: a buffer.
* @content_type:
* @buffer: an #hb_buffer_t.
* @content_type: the type of buffer contents to set
*
*
* Sets the type of @buffer contents, buffers are either empty, contain
* characters (before shaping) or glyphs (the result of shaping).
*
* Since: 0.9.5
**/
@ -874,11 +897,12 @@ hb_buffer_set_content_type (hb_buffer_t *buffer,
/**
* hb_buffer_get_content_type:
* @buffer: a buffer.
* @buffer: an #hb_buffer_t.
*
*
* see hb_buffer_set_content_type().
*
* Return value:
* Return value:
* The type of @buffer contents.
*
* Since: 0.9.5
**/
@ -891,7 +915,7 @@ hb_buffer_get_content_type (hb_buffer_t *buffer)
/**
* hb_buffer_set_unicode_funcs:
* @buffer: a buffer.
* @buffer: an #hb_buffer_t.
* @unicode_funcs:
*
*
@ -916,7 +940,7 @@ hb_buffer_set_unicode_funcs (hb_buffer_t *buffer,
/**
* hb_buffer_get_unicode_funcs:
* @buffer: a buffer.
* @buffer: an #hb_buffer_t.
*
*
*
@ -932,10 +956,16 @@ hb_buffer_get_unicode_funcs (hb_buffer_t *buffer)
/**
* hb_buffer_set_direction:
* @buffer: a buffer.
* @direction:
* @buffer: an #hb_buffer_t.
* @direction: the #hb_direction_t of the @buffer
*
*
* Set the text flow direction of the buffer. No shaping can happen without
* setting @buffer direction, and it controls the visual direction for the
* output glyphs; for RTL direction the glyphs will be reversed. Many layout
* features depend on the proper setting of the direction, for example,
* reversing RTL text before shaping, then shaping with LTR direction is not
* the same as keeping the text in logical order and shaping with RTL
* direction.
*
* Since: 0.9.2
**/
@ -952,11 +982,12 @@ hb_buffer_set_direction (hb_buffer_t *buffer,
/**
* hb_buffer_get_direction:
* @buffer: a buffer.
* @buffer: an #hb_buffer_t.
*
*
* See hb_buffer_set_direction()
*
* Return value:
* Return value:
* The direction of the @buffer.
*
* Since: 0.9.2
**/
@ -968,10 +999,18 @@ hb_buffer_get_direction (hb_buffer_t *buffer)
/**
* hb_buffer_set_script:
* @buffer: a buffer.
* @script:
* @buffer: an #hb_buffer_t.
* @script: an #hb_script_t to set.
*
*
* Sets the script of @buffer to @script.
*
* Script is crucial for choosing the proper shaping behaviour for scripts that
* require it (e.g. Arabic) and the which OpenType features defined in the font
* to be applied.
*
* You can pass one of the predefined #hb_script_t values, or use
* hb_script_from_string() or hb_script_from_iso15924_tag() to get the
* corresponding script from an ISO 15924 script tag.
*
* Since: 0.9.2
**/
@ -987,11 +1026,12 @@ hb_buffer_set_script (hb_buffer_t *buffer,
/**
* hb_buffer_get_script:
* @buffer: a buffer.
* @buffer: an #hb_buffer_t.
*
*
* See hb_buffer_set_script().
*
* Return value:
* Return value:
* The #hb_script_t of the @buffer.
*
* Since: 0.9.2
**/
@ -1003,10 +1043,18 @@ hb_buffer_get_script (hb_buffer_t *buffer)
/**
* hb_buffer_set_language:
* @buffer: a buffer.
* @language:
* @buffer: an #hb_buffer_t.
* @language: an hb_language_t to set.
*
*
* Sets the language of @buffer to @language.
*
* Languages are crucial for selecting which OpenType feature to apply to the
* buffer which can result in applying language-specific behaviour. Languages
* are orthogonal to the scripts, and though they are related, they are
* different concepts and should not be confused with each other.
*
* Use hb_language_from_string() to convert from ISO 639 language codes to
* #hb_language_t.
*
* Since: 0.9.2
**/
@ -1022,11 +1070,12 @@ hb_buffer_set_language (hb_buffer_t *buffer,
/**
* hb_buffer_get_language:
* @buffer: a buffer.
* @buffer: an #hb_buffer_t.
*
*
* See hb_buffer_set_language().
*
* Return value: (transfer none):
* The #hb_language_t of the buffer. Must not be freed by the caller.
*
* Since: 0.9.2
**/
@ -1038,10 +1087,12 @@ hb_buffer_get_language (hb_buffer_t *buffer)
/**
* hb_buffer_set_segment_properties:
* @buffer: a buffer.
* @props:
* @buffer: an #hb_buffer_t.
* @props: an #hb_segment_properties_t to use.
*
*
* Sets the segment properties of the buffer, a shortcut for calling
* hb_buffer_set_direction(), hb_buffer_set_script() and
* hb_buffer_set_language() individually.
*
* Since: 0.9.7
**/
@ -1057,10 +1108,10 @@ hb_buffer_set_segment_properties (hb_buffer_t *buffer,
/**
* hb_buffer_get_segment_properties:
* @buffer: a buffer.
* @props: (out):
* @buffer: an #hb_buffer_t.
* @props: (out): the output #hb_segment_properties_t.
*
*
* Sets @props to the #hb_segment_properties_t of @buffer.
*
* Since: 0.9.7
**/
@ -1074,10 +1125,10 @@ hb_buffer_get_segment_properties (hb_buffer_t *buffer,
/**
* hb_buffer_set_flags:
* @buffer: a buffer.
* @flags:
* @buffer: an #hb_buffer_t.
* @flags: the buffer flags to set.
*
*
* Sets @buffer flags to @flags. See #hb_buffer_flags_t.
*
* Since: 0.9.7
**/
@ -1093,11 +1144,12 @@ hb_buffer_set_flags (hb_buffer_t *buffer,
/**
* hb_buffer_get_flags:
* @buffer: a buffer.
* @buffer: an #hb_buffer_t.
*
*
* See hb_buffer_set_flags().
*
* Return value:
* The @buffer flags.
*
* Since: 0.9.7
**/
@ -1109,7 +1161,7 @@ hb_buffer_get_flags (hb_buffer_t *buffer)
/**
* hb_buffer_set_cluster_level:
* @buffer: a buffer.
* @buffer: an #hb_buffer_t.
* @cluster_level:
*
*
@ -1128,7 +1180,7 @@ hb_buffer_set_cluster_level (hb_buffer_t *buffer,
/**
* hb_buffer_get_cluster_level:
* @buffer: a buffer.
* @buffer: an #hb_buffer_t.
*
*
*
@ -1145,10 +1197,13 @@ hb_buffer_get_cluster_level (hb_buffer_t *buffer)
/**
* hb_buffer_set_replacement_codepoint:
* @buffer: a buffer.
* @replacement:
* @buffer: an #hb_buffer_t.
* @replacement: the replacement #hb_codepoint_t
*
*
* Sets the #hb_codepoint_t that replaces invalid entries for a given encoding
* when adding text to @buffer.
*
* Default is %HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT.
*
* Since: 0.9.31
**/
@ -1164,11 +1219,12 @@ hb_buffer_set_replacement_codepoint (hb_buffer_t *buffer,
/**
* hb_buffer_get_replacement_codepoint:
* @buffer: a buffer.
* @buffer: an #hb_buffer_t.
*
*
* See hb_buffer_set_replacement_codepoint().
*
* Return value:
* The @buffer replacement #hb_codepoint_t.
*
* Since: 0.9.31
**/
@ -1181,9 +1237,10 @@ hb_buffer_get_replacement_codepoint (hb_buffer_t *buffer)
/**
* hb_buffer_reset:
* @buffer: a buffer.
* @buffer: an #hb_buffer_t.
*
*
* Resets the buffer to its initial status, as if it was just newly created
* with hb_buffer_create().
*
* Since: 0.9.2
**/
@ -1195,9 +1252,10 @@ hb_buffer_reset (hb_buffer_t *buffer)
/**
* hb_buffer_clear_contents:
* @buffer: a buffer.
* @buffer: an #hb_buffer_t.
*
*
* Similar to hb_buffer_reset(), but does not clear the Unicode functions and
* the replacement code point.
*
* Since: 0.9.11
**/
@ -1209,12 +1267,13 @@ hb_buffer_clear_contents (hb_buffer_t *buffer)
/**
* hb_buffer_pre_allocate:
* @buffer: a buffer.
* @size:
* @buffer: an #hb_buffer_t.
* @size: number of items to pre allocate.
*
*
* Pre allocates memory for @buffer to fit at least @size number of items.
*
* Return value:
* Return value:
* %true if @buffer memory allocation succeeded, %false otherwise.
*
* Since: 0.9.2
**/
@ -1226,11 +1285,12 @@ hb_buffer_pre_allocate (hb_buffer_t *buffer, unsigned int size)
/**
* hb_buffer_allocation_successful:
* @buffer: a buffer.
* @buffer: an #hb_buffer_t.
*
*
* Check if allocating memory for the buffer succeeded.
*
* Return value:
* Return value:
* %true if @buffer memory allocation succeeded, %false otherwise.
*
* Since: 0.9.2
**/
@ -1242,11 +1302,18 @@ hb_buffer_allocation_successful (hb_buffer_t *buffer)
/**
* hb_buffer_add:
* @buffer: a buffer.
* @codepoint:
* @cluster:
* @buffer: an #hb_buffer_t.
* @codepoint: a Unicode code point.
* @cluster: the cluster value of @codepoint.
*
*
* Appends a character with the Unicode value of @codepoint to @buffer, and
* gives it the initial cluster value of @cluster. Clusters can be any thing
* the client wants, they are usually used to refer to the index of the
* character in the input text stream and are output in
* #hb_glyph_info_t.cluster field.
*
* This function does not check the validity of @codepoint, it is up to the
* caller to ensure it is a valid Unicode code point.
*
* Since: 0.9.7
**/
@ -1261,12 +1328,14 @@ hb_buffer_add (hb_buffer_t *buffer,
/**
* hb_buffer_set_length:
* @buffer: a buffer.
* @length:
* @buffer: an #hb_buffer_t.
* @length: the new length of @buffer.
*
*
* Similar to hb_buffer_pre_allocate(), but clears any new items added at the
* end.
*
* Return value:
* %true if @buffer memory allocation succeeded, %false otherwise.
*
* Since: 0.9.2
**/
@ -1301,11 +1370,13 @@ hb_buffer_set_length (hb_buffer_t *buffer,
/**
* hb_buffer_get_length:
* @buffer: a buffer.
* @buffer: an #hb_buffer_t.
*
* Returns the number of items in the buffer.
*
* Return value: buffer length.
* Return value:
* The @buffer length.
* The value valid as long as buffer has not been modified.
*
* Since: 0.9.2
**/
@ -1317,13 +1388,15 @@ hb_buffer_get_length (hb_buffer_t *buffer)
/**
* hb_buffer_get_glyph_infos:
* @buffer: a buffer.
* @buffer: an #hb_buffer_t.
* @length: (out): output array length.
*
* Returns buffer glyph information array. Returned pointer
* is valid as long as buffer contents are not modified.
* 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.
* Return value: (transfer none) (array length=length):
* The @buffer glyph information array.
* The value valid as long as buffer has not been modified.
*
* Since: 0.9.2
**/
@ -1339,13 +1412,15 @@ hb_buffer_get_glyph_infos (hb_buffer_t *buffer,
/**
* hb_buffer_get_glyph_positions:
* @buffer: a buffer.
* @buffer: an #hb_buffer_t.
* @length: (out): output length.
*
* Returns buffer glyph position array. Returned pointer
* is valid as long as buffer contents are not modified.
* 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.
* Return value: (transfer none) (array length=length):
* The @buffer glyph position array.
* The value valid as long as buffer has not been modified.
*
* Since: 0.9.2
**/
@ -1364,7 +1439,7 @@ hb_buffer_get_glyph_positions (hb_buffer_t *buffer,
/**
* hb_buffer_reverse:
* @buffer: a buffer.
* @buffer: an #hb_buffer_t.
*
* Reverses buffer contents.
*
@ -1378,7 +1453,7 @@ hb_buffer_reverse (hb_buffer_t *buffer)
/**
* hb_buffer_reverse_range:
* @buffer: a buffer.
* @buffer: an #hb_buffer_t.
* @start: start index.
* @end: end index.
*
@ -1395,7 +1470,7 @@ hb_buffer_reverse_range (hb_buffer_t *buffer,
/**
* hb_buffer_reverse_clusters:
* @buffer: a buffer.
* @buffer: an #hb_buffer_t.
*
* Reverses buffer clusters. That is, the buffer contents are
* reversed, then each cluster (consecutive items having the
@ -1411,7 +1486,7 @@ hb_buffer_reverse_clusters (hb_buffer_t *buffer)
/**
* hb_buffer_guess_segment_properties:
* @buffer: a buffer.
* @buffer: an #hb_buffer_t.
*
* Sets unset buffer segment properties based on buffer Unicode
* contents. If buffer is not empty, it must have content type
@ -1510,13 +1585,18 @@ hb_buffer_add_utf (hb_buffer_t *buffer,
/**
* hb_buffer_add_utf8:
* @buffer: a buffer.
* @text: (array length=text_length) (element-type uint8_t):
* @text_length:
* @item_offset:
* @item_length:
* @buffer: an #hb_buffer_t.
* @text: (array length=text_length) (element-type uint8_t): an array of UTF-8
* characters to append.
* @text_length: the length of the @text, or -1 if it is %NULL terminated.
* @item_offset: the offset of the first character to add to the @buffer.
* @item_length: the number of characters to add to the @buffer, or -1 for the
* end of @text (assuming it is %NULL terminated).
*
*
* See hb_buffer_add_codepoints().
*
* Replaces invalid UTF-8 characters with the @buffer replacement code point,
* see hb_buffer_set_replacement_codepoint().
*
* Since: 0.9.2
**/
@ -1532,13 +1612,17 @@ hb_buffer_add_utf8 (hb_buffer_t *buffer,
/**
* hb_buffer_add_utf16:
* @buffer: a buffer.
* @text: (array length=text_length):
* @text_length:
* @item_offset:
* @item_length:
* @buffer: an #hb_buffer_t.
* @text: (array length=text_length): an array of UTF-16 characters to append.
* @text_length: the length of the @text, or -1 if it is %NULL terminated.
* @item_offset: the offset of the first character to add to the @buffer.
* @item_length: the number of characters to add to the @buffer, or -1 for the
* end of @text (assuming it is %NULL terminated).
*
*
* See hb_buffer_add_codepoints().
*
* Replaces invalid UTF-16 characters with the @buffer replacement code point,
* see hb_buffer_set_replacement_codepoint().
*
* Since: 0.9.2
**/
@ -1554,13 +1638,17 @@ hb_buffer_add_utf16 (hb_buffer_t *buffer,
/**
* hb_buffer_add_utf32:
* @buffer: a buffer.
* @text: (array length=text_length):
* @text_length:
* @item_offset:
* @item_length:
* @buffer: an #hb_buffer_t.
* @text: (array length=text_length): an array of UTF-32 characters to append.
* @text_length: the length of the @text, or -1 if it is %NULL terminated.
* @item_offset: the offset of the first character to add to the @buffer.
* @item_length: the number of characters to add to the @buffer, or -1 for the
* end of @text (assuming it is %NULL terminated).
*
*
* See hb_buffer_add_codepoints().
*
* Replaces invalid UTF-32 characters with the @buffer replacement code point,
* see hb_buffer_set_replacement_codepoint().
*
* Since: 0.9.2
**/
@ -1576,13 +1664,18 @@ hb_buffer_add_utf32 (hb_buffer_t *buffer,
/**
* hb_buffer_add_latin1:
* @buffer: a buffer.
* @text: (array length=text_length) (element-type uint8_t):
* @text_length:
* @item_offset:
* @item_length:
* @buffer: an #hb_buffer_t.
* @text: (array length=text_length) (element-type uint8_t): an array of UTF-8
* characters to append.
* @text_length: the length of the @text, or -1 if it is %NULL terminated.
* @item_offset: the offset of the first character to add to the @buffer.
* @item_length: the number of characters to add to the @buffer, or -1 for the
* end of @text (assuming it is %NULL terminated).
*
*
* Similar to hb_buffer_add_codepoints(), but allows only access to first 256
* Unicode code points that can fit in 8-bit strings.
*
* <note>Has nothing to do with non-Unicode Latin-1 encoding.</note>
*
* Since: 0.9.39
**/
@ -1598,13 +1691,25 @@ hb_buffer_add_latin1 (hb_buffer_t *buffer,
/**
* hb_buffer_add_codepoints:
* @buffer: a buffer.
* @text: (array length=text_length):
* @text_length:
* @item_offset:
* @item_length:
* @buffer: a #hb_buffer_t to append characters to.
* @text: (array length=text_length): an array of Unicode code points to append.
* @text_length: the length of the @text, or -1 if it is %NULL terminated.
* @item_offset: the offset of the first code point to add to the @buffer.
* @item_length: the number of code points to add to the @buffer, or -1 for the
* end of @text (assuming it is %NULL terminated).
*
*
* Appends characters from @text array to @buffer. The @item_offset is the
* position of the first character from @text that will be appended, and
* @item_length is the number of character. When shaping part of a larger text
* (e.g. a run of text from a paragraph), instead of passing just the substring
* corresponding to the run, it is preferable to pass the whole
* paragraph and specify the run start and length as @item_offset and
* @item_length, respectively, to give HarfBuzz the full context to be able,
* for example, to do cross-run Arabic shaping or properly handle combining
* marks at stat of run.
*
* This function does not check the validity of @text, it is up to the caller
* to ensure it contains a valid Unicode code points.
*
* Since: 0.9.31
**/
@ -1676,9 +1781,12 @@ normalize_glyphs_cluster (hb_buffer_t *buffer,
/**
* hb_buffer_normalize_glyphs:
* @buffer: a buffer.
* @buffer: an #hb_buffer_t.
*
*
* Reorders a glyph buffer to have canonical in-cluster glyph order / position.
* The resulting clusters should behave identical to pre-reordering clusters.
*
* <note>This has nothing to do with Unicode normalization.</note>
*
* Since: 0.9.2
**/
@ -1724,3 +1832,45 @@ hb_buffer_t::sort (unsigned int start, unsigned int end, int(*compar)(const hb_g
}
}
}
/*
* Debugging.
*/
/**
* hb_buffer_set_message_func:
* @buffer: an #hb_buffer_t.
* @func: (closure user_data) (destroy destroy) (scope notified):
* @user_data:
* @destroy:
*
*
*
* Since: 1.1.3
**/
void
hb_buffer_set_message_func (hb_buffer_t *buffer,
hb_buffer_message_func_t func,
void *user_data, hb_destroy_func_t destroy)
{
if (buffer->message_destroy)
buffer->message_destroy (buffer->message_data);
if (func) {
buffer->message_func = func;
buffer->message_data = user_data;
buffer->message_destroy = destroy;
} else {
buffer->message_func = NULL;
buffer->message_data = NULL;
buffer->message_destroy = NULL;
}
}
bool
hb_buffer_t::message_impl (hb_font_t *font, const char *fmt, va_list ap)
{
char buf[100];
vsnprintf (buf, sizeof (buf), fmt, ap);
return (bool) this->message_func (this, font, buf, this->message_data);
}

View File

@ -40,7 +40,27 @@
HB_BEGIN_DECLS
/**
* hb_glyph_info_t:
* @codepoint: either a Unicode code point (before shaping) or a glyph index
* (after shaping).
* @mask:
* @cluster: the index of the character in the original text that corresponds
* to this #hb_glyph_info_t, or whatever the client passes to
* hb_buffer_add(). More than one #hb_glyph_info_t can have the same
* @cluster value, if they resulted from the same character (e.g. one
* to many glyph substitution), and when more than one character gets
* merged in the same glyph (e.g. many to one glyph substitution) the
* #hb_glyph_info_t will have the smallest cluster value of them.
* By default some characters are merged into the same cluster
* (e.g. combining marks have the same cluster as their bases)
* even if they are separate glyphs, hb_buffer_set_cluster_level()
* allow selecting more fine-grained cluster handling.
*
* The #hb_glyph_info_t is the structure that holds information about the
* glyphs and their relation to input text.
*
*/
typedef struct hb_glyph_info_t {
hb_codepoint_t codepoint;
hb_mask_t mask;
@ -51,6 +71,22 @@ typedef struct hb_glyph_info_t {
hb_var_int_t var2;
} hb_glyph_info_t;
/**
* hb_glyph_position_t:
* @x_advance: how much the line advances after drawing this glyph when setting
* text in horizontal direction.
* @y_advance: how much the line advances after drawing this glyph when setting
* text in vertical direction.
* @x_offset: how much the glyph moves on the X-axis before drawing it, this
* should not affect how much the line advances.
* @y_offset: how much the glyph moves on the Y-axis before drawing it, this
* should not affect how much the line advances.
*
* The #hb_glyph_position_t is the structure that holds the positions of the
* glyph in both horizontal and vertical directions. All positions in
* #hb_glyph_position_t are relative to the current point.
*
*/
typedef struct hb_glyph_position_t {
hb_position_t x_advance;
hb_position_t y_advance;
@ -61,7 +97,16 @@ typedef struct hb_glyph_position_t {
hb_var_int_t var;
} hb_glyph_position_t;
/**
* hb_segment_properties_t:
* @direction: the #hb_direction_t of the buffer, see hb_buffer_set_direction().
* @script: the #hb_script_t of the buffer, see hb_buffer_set_script().
* @language: the #hb_language_t of the buffer, see hb_buffer_set_language().
*
* The structure that holds various text properties of an #hb_buffer_t. Can be
* set and retrieved using hb_buffer_set_segment_properties() and
* hb_buffer_get_segment_properties(), respectively.
*/
typedef struct hb_segment_properties_t {
hb_direction_t direction;
hb_script_t script;
@ -77,101 +122,125 @@ typedef struct hb_segment_properties_t {
NULL, \
NULL}
hb_bool_t
HB_EXTERN hb_bool_t
hb_segment_properties_equal (const hb_segment_properties_t *a,
const hb_segment_properties_t *b);
unsigned int
HB_EXTERN unsigned int
hb_segment_properties_hash (const hb_segment_properties_t *p);
/*
* hb_buffer_t
/**
* hb_buffer_t:
*
* The main structure holding the input text and its properties before shaping,
* and output glyphs and their information after shaping.
*/
typedef struct hb_buffer_t hb_buffer_t;
hb_buffer_t *
HB_EXTERN hb_buffer_t *
hb_buffer_create (void);
hb_buffer_t *
HB_EXTERN hb_buffer_t *
hb_buffer_get_empty (void);
hb_buffer_t *
HB_EXTERN hb_buffer_t *
hb_buffer_reference (hb_buffer_t *buffer);
void
HB_EXTERN void
hb_buffer_destroy (hb_buffer_t *buffer);
hb_bool_t
HB_EXTERN hb_bool_t
hb_buffer_set_user_data (hb_buffer_t *buffer,
hb_user_data_key_t *key,
void * data,
hb_destroy_func_t destroy,
hb_bool_t replace);
void *
HB_EXTERN void *
hb_buffer_get_user_data (hb_buffer_t *buffer,
hb_user_data_key_t *key);
/**
* hb_buffer_content_type_t:
* @HB_BUFFER_CONTENT_TYPE_INVALID: Initial value for new buffer.
* @HB_BUFFER_CONTENT_TYPE_UNICODE: The buffer contains input characters (before shaping).
* @HB_BUFFER_CONTENT_TYPE_GLYPHS: The buffer contains output glyphs (after shaping).
*/
typedef enum {
HB_BUFFER_CONTENT_TYPE_INVALID = 0,
HB_BUFFER_CONTENT_TYPE_UNICODE,
HB_BUFFER_CONTENT_TYPE_GLYPHS
} hb_buffer_content_type_t;
void
HB_EXTERN void
hb_buffer_set_content_type (hb_buffer_t *buffer,
hb_buffer_content_type_t content_type);
hb_buffer_content_type_t
HB_EXTERN hb_buffer_content_type_t
hb_buffer_get_content_type (hb_buffer_t *buffer);
void
HB_EXTERN void
hb_buffer_set_unicode_funcs (hb_buffer_t *buffer,
hb_unicode_funcs_t *unicode_funcs);
hb_unicode_funcs_t *
HB_EXTERN hb_unicode_funcs_t *
hb_buffer_get_unicode_funcs (hb_buffer_t *buffer);
void
HB_EXTERN void
hb_buffer_set_direction (hb_buffer_t *buffer,
hb_direction_t direction);
hb_direction_t
HB_EXTERN hb_direction_t
hb_buffer_get_direction (hb_buffer_t *buffer);
void
HB_EXTERN void
hb_buffer_set_script (hb_buffer_t *buffer,
hb_script_t script);
hb_script_t
HB_EXTERN hb_script_t
hb_buffer_get_script (hb_buffer_t *buffer);
void
HB_EXTERN void
hb_buffer_set_language (hb_buffer_t *buffer,
hb_language_t language);
hb_language_t
HB_EXTERN hb_language_t
hb_buffer_get_language (hb_buffer_t *buffer);
void
HB_EXTERN void
hb_buffer_set_segment_properties (hb_buffer_t *buffer,
const hb_segment_properties_t *props);
void
HB_EXTERN void
hb_buffer_get_segment_properties (hb_buffer_t *buffer,
hb_segment_properties_t *props);
void
HB_EXTERN void
hb_buffer_guess_segment_properties (hb_buffer_t *buffer);
/*
/**
* hb_buffer_flags_t:
* @HB_BUFFER_FLAG_DEFAULT: the default buffer flag.
* @HB_BUFFER_FLAG_BOT: flag indicating that special handling of the beginning
* of text paragraph can be applied to this buffer. Should usually
* be set, unless you are passing to the buffer only part
* of the text without the full context.
* @HB_BUFFER_FLAG_EOT: flag indicating that special handling of the end of text
* paragraph can be applied to this buffer, similar to
* @HB_BUFFER_FLAG_EOT.
* @HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES:
* flag indication that character with Default_Ignorable
* Unicode property should use the corresponding glyph
* from the font, instead of hiding them (currently done
* by replacing them with the space glyph and zeroing the
* advance width.)
*
* Since: 0.9.20
*/
typedef enum { /*< flags >*/
@ -181,11 +250,11 @@ typedef enum { /*< flags >*/
HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES = 0x00000004u
} hb_buffer_flags_t;
void
HB_EXTERN void
hb_buffer_set_flags (hb_buffer_t *buffer,
hb_buffer_flags_t flags);
hb_buffer_flags_t
HB_EXTERN hb_buffer_flags_t
hb_buffer_get_flags (hb_buffer_t *buffer);
/*
@ -198,93 +267,92 @@ typedef enum {
HB_BUFFER_CLUSTER_LEVEL_DEFAULT = HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES
} hb_buffer_cluster_level_t;
void
HB_EXTERN void
hb_buffer_set_cluster_level (hb_buffer_t *buffer,
hb_buffer_cluster_level_t cluster_level);
hb_buffer_cluster_level_t
HB_EXTERN hb_buffer_cluster_level_t
hb_buffer_get_cluster_level (hb_buffer_t *buffer);
/**
* HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT:
*
* The default code point for replacing invalid characters in a given encoding.
* Set to U+FFFD REPLACEMENT CHARACTER.
*
* Since: 0.9.31
*/
#define HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT 0xFFFDu
/* Sets codepoint used to replace invalid UTF-8/16/32 entries.
* Default is 0xFFFDu. */
void
HB_EXTERN void
hb_buffer_set_replacement_codepoint (hb_buffer_t *buffer,
hb_codepoint_t replacement);
hb_codepoint_t
HB_EXTERN hb_codepoint_t
hb_buffer_get_replacement_codepoint (hb_buffer_t *buffer);
/* Resets the buffer. Afterwards it's as if it was just created,
* except that it has a larger buffer allocated perhaps... */
void
HB_EXTERN void
hb_buffer_reset (hb_buffer_t *buffer);
/* Like reset, but does NOT clear unicode_funcs and replacement_codepoint. */
void
HB_EXTERN void
hb_buffer_clear_contents (hb_buffer_t *buffer);
/* Returns false if allocation failed */
hb_bool_t
HB_EXTERN hb_bool_t
hb_buffer_pre_allocate (hb_buffer_t *buffer,
unsigned int size);
/* Returns false if allocation has failed before */
hb_bool_t
HB_EXTERN hb_bool_t
hb_buffer_allocation_successful (hb_buffer_t *buffer);
void
HB_EXTERN void
hb_buffer_reverse (hb_buffer_t *buffer);
void
HB_EXTERN void
hb_buffer_reverse_range (hb_buffer_t *buffer,
unsigned int start, unsigned int end);
void
HB_EXTERN void
hb_buffer_reverse_clusters (hb_buffer_t *buffer);
/* Filling the buffer in */
void
HB_EXTERN void
hb_buffer_add (hb_buffer_t *buffer,
hb_codepoint_t codepoint,
unsigned int cluster);
void
HB_EXTERN void
hb_buffer_add_utf8 (hb_buffer_t *buffer,
const char *text,
int text_length,
unsigned int item_offset,
int item_length);
void
HB_EXTERN void
hb_buffer_add_utf16 (hb_buffer_t *buffer,
const uint16_t *text,
int text_length,
unsigned int item_offset,
int item_length);
void
HB_EXTERN void
hb_buffer_add_utf32 (hb_buffer_t *buffer,
const uint32_t *text,
int text_length,
unsigned int item_offset,
int item_length);
/* Allows only access to first 256 Unicode codepoints. */
void
HB_EXTERN void
hb_buffer_add_latin1 (hb_buffer_t *buffer,
const uint8_t *text,
int text_length,
unsigned int item_offset,
int item_length);
/* Like add_utf32 but does NOT check for invalid Unicode codepoints. */
void
HB_EXTERN void
hb_buffer_add_codepoints (hb_buffer_t *buffer,
const hb_codepoint_t *text,
int text_length,
@ -292,32 +360,25 @@ hb_buffer_add_codepoints (hb_buffer_t *buffer,
int item_length);
/* Clears any new items added at the end */
hb_bool_t
HB_EXTERN hb_bool_t
hb_buffer_set_length (hb_buffer_t *buffer,
unsigned int length);
/* Return value valid as long as buffer not modified */
unsigned int
HB_EXTERN unsigned int
hb_buffer_get_length (hb_buffer_t *buffer);
/* Getting glyphs out of the buffer */
/* Return value valid as long as buffer not modified */
hb_glyph_info_t *
HB_EXTERN hb_glyph_info_t *
hb_buffer_get_glyph_infos (hb_buffer_t *buffer,
unsigned int *length);
/* Return value valid as long as buffer not modified */
hb_glyph_position_t *
HB_EXTERN hb_glyph_position_t *
hb_buffer_get_glyph_positions (hb_buffer_t *buffer,
unsigned int *length);
/* Reorders a glyph buffer to have canonical in-cluster glyph order / position.
* The resulting clusters should behave identical to pre-reordering clusters.
* NOTE: This has nothing to do with Unicode normalization. */
void
HB_EXTERN void
hb_buffer_normalize_glyphs (hb_buffer_t *buffer);
@ -325,7 +386,16 @@ hb_buffer_normalize_glyphs (hb_buffer_t *buffer);
* Serialize
*/
/*
/**
* hb_buffer_serialize_flags_t:
* @HB_BUFFER_SERIALIZE_FLAG_DEFAULT: serialize glyph names, clusters and positions.
* @HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS: do not serialize glyph cluster.
* @HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS: do not serialize glyph position information.
* @HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES: do no serialize glyph name.
* @HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS: serialize glyph extents.
*
* Flags that control what glyph information are serialized in hb_buffer_serialize_glyphs().
*
* Since: 0.9.20
*/
typedef enum { /*< flags >*/
@ -336,43 +406,67 @@ typedef enum { /*< flags >*/
HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS = 0x00000008u
} hb_buffer_serialize_flags_t;
/**
* hb_buffer_serialize_format_t:
* @HB_BUFFER_SERIALIZE_FORMAT_TEXT: a human-readable, plain text format.
* @HB_BUFFER_SERIALIZE_FORMAT_JSON: a machine-readable JSON format.
* @HB_BUFFER_SERIALIZE_FORMAT_INVALID: invalid format.
*
* The buffer serialization and de-serialization format used in
* hb_buffer_serialize_glyphs() and hb_buffer_deserialize_glyphs().
*
* Since: 0.9.2
*/
typedef enum {
HB_BUFFER_SERIALIZE_FORMAT_TEXT = HB_TAG('T','E','X','T'),
HB_BUFFER_SERIALIZE_FORMAT_JSON = HB_TAG('J','S','O','N'),
HB_BUFFER_SERIALIZE_FORMAT_INVALID = HB_TAG_NONE
} hb_buffer_serialize_format_t;
/* len=-1 means str is NUL-terminated. */
hb_buffer_serialize_format_t
HB_EXTERN hb_buffer_serialize_format_t
hb_buffer_serialize_format_from_string (const char *str, int len);
const char *
HB_EXTERN const char *
hb_buffer_serialize_format_to_string (hb_buffer_serialize_format_t format);
const char **
HB_EXTERN const char **
hb_buffer_serialize_list_formats (void);
/* Returns number of items, starting at start, that were serialized. */
unsigned int
HB_EXTERN unsigned int
hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
unsigned int start,
unsigned int end,
char *buf,
unsigned int buf_size,
unsigned int *buf_consumed, /* May be NULL */
hb_font_t *font, /* May be NULL */
unsigned int *buf_consumed,
hb_font_t *font,
hb_buffer_serialize_format_t format,
hb_buffer_serialize_flags_t flags);
hb_bool_t
HB_EXTERN hb_bool_t
hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
const char *buf,
int buf_len, /* -1 means nul-terminated */
const char **end_ptr, /* May be NULL */
hb_font_t *font, /* May be NULL */
int buf_len,
const char **end_ptr,
hb_font_t *font,
hb_buffer_serialize_format_t format);
/*
* Debugging.
*/
typedef hb_bool_t (*hb_buffer_message_func_t) (hb_buffer_t *buffer,
hb_font_t *font,
const char *message,
void *user_data);
HB_EXTERN void
hb_buffer_set_message_func (hb_buffer_t *buffer,
hb_buffer_message_func_t func,
void *user_data, hb_destroy_func_t destroy);
HB_END_DECLS
#endif /* HB_BUFFER_H */

View File

@ -281,12 +281,15 @@ retry:
/**
* hb_language_from_string:
* @str: (array length=len) (element-type uint8_t):
* @len:
* @str: (array length=len) (element-type uint8_t): a string representing
* ISO 639 language code
* @len: length of the @str, or -1 if it is %NULL-terminated.
*
*
* Converts @str representing an ISO 639 language code to the corresponding
* #hb_language_t.
*
* Return value: (transfer none):
* The #hb_language_t corresponding to the ISO 639 language code.
*
* Since: 0.9.2
**/
@ -314,11 +317,13 @@ hb_language_from_string (const char *str, int len)
/**
* hb_language_to_string:
* @language:
* @language: an #hb_language_t to convert.
*
*
* See hb_language_from_string().
*
* Return value: (transfer none):
* Return value: (transfer none):
* A %NULL-terminated string representing the @language. Must not be freed by
* the caller.
*
* Since: 0.9.2
**/
@ -357,11 +362,12 @@ hb_language_get_default (void)
/**
* hb_script_from_iso15924_tag:
* @tag:
* @tag: an #hb_tag_t representing an ISO 15924 tag.
*
*
* Converts an ISO 15924 script tag to a corresponding #hb_script_t.
*
* Return value:
* An #hb_script_t corresponding to the ISO 15924 tag.
*
* Since: 0.9.2
**/
@ -401,28 +407,33 @@ hb_script_from_iso15924_tag (hb_tag_t tag)
/**
* hb_script_from_string:
* @s: (array length=len) (element-type uint8_t):
* @len:
* @str: (array length=len) (element-type uint8_t): a string representing an
* ISO 15924 tag.
* @len: length of the @str, or -1 if it is %NULL-terminated.
*
*
* Converts a string @str representing an ISO 15924 script tag to a
* corresponding #hb_script_t. Shorthand for hb_tag_from_string() then
* hb_script_from_iso15924_tag().
*
* Return value:
* An #hb_script_t corresponding to the ISO 15924 tag.
*
* Since: 0.9.2
**/
hb_script_t
hb_script_from_string (const char *s, int len)
hb_script_from_string (const char *str, int len)
{
return hb_script_from_iso15924_tag (hb_tag_from_string (s, len));
return hb_script_from_iso15924_tag (hb_tag_from_string (str, len));
}
/**
* hb_script_to_iso15924_tag:
* @script:
* @script: an #hb_script_ to convert.
*
*
* See hb_script_from_iso15924_tag().
*
* Return value:
* Return value:
* An #hb_tag_t representing an ISO 15924 script tag.
*
* Since: 0.9.2
**/
@ -521,7 +532,7 @@ hb_user_data_array_t::set (hb_user_data_key_t *key,
}
}
hb_user_data_item_t item = {key, data, destroy};
bool ret = !!items.replace_or_insert (item, lock, replace);
bool ret = !!items.replace_or_insert (item, lock, (bool) replace);
return ret;
}

View File

@ -98,16 +98,22 @@ typedef uint32_t hb_tag_t;
#define HB_TAG_MAX_SIGNED HB_TAG(0x7f,0xff,0xff,0xff)
/* len=-1 means str is NUL-terminated. */
hb_tag_t
HB_EXTERN hb_tag_t
hb_tag_from_string (const char *str, int len);
/* buf should have 4 bytes. */
void
HB_EXTERN void
hb_tag_to_string (hb_tag_t tag, char *buf);
/* hb_direction_t */
/**
* hb_direction_t:
* @HB_DIRECTION_INVALID: Initial, unset direction.
* @HB_DIRECTION_LTR: Text is set horizontally from left to right.
* @HB_DIRECTION_RTL: Text is set horizontally from right to left.
* @HB_DIRECTION_TTB: Text is set vertically from top to bottom.
* @HB_DIRECTION_BTT: Text is set vertically from bottom to top.
*/
typedef enum {
HB_DIRECTION_INVALID = 0,
HB_DIRECTION_LTR = 4,
@ -117,10 +123,10 @@ typedef enum {
} hb_direction_t;
/* len=-1 means str is NUL-terminated */
hb_direction_t
HB_EXTERN hb_direction_t
hb_direction_from_string (const char *str, int len);
const char *
HB_EXTERN const char *
hb_direction_to_string (hb_direction_t direction);
#define HB_DIRECTION_IS_VALID(dir) ((((unsigned int) (dir)) & ~3U) == 4)
@ -136,16 +142,15 @@ hb_direction_to_string (hb_direction_t direction);
typedef const struct hb_language_impl_t *hb_language_t;
/* len=-1 means str is NUL-terminated */
hb_language_t
HB_EXTERN hb_language_t
hb_language_from_string (const char *str, int len);
const char *
HB_EXTERN const char *
hb_language_to_string (hb_language_t language);
#define HB_LANGUAGE_INVALID ((hb_language_t) NULL)
hb_language_t
HB_EXTERN hb_language_t
hb_language_get_default (void);
@ -324,18 +329,16 @@ typedef enum
/* Script functions */
hb_script_t
HB_EXTERN hb_script_t
hb_script_from_iso15924_tag (hb_tag_t tag);
/* sugar for tag_from_string() then script_from_iso15924_tag */
/* len=-1 means s is NUL-terminated */
hb_script_t
hb_script_from_string (const char *s, int len);
HB_EXTERN hb_script_t
hb_script_from_string (const char *str, int len);
hb_tag_t
HB_EXTERN hb_tag_t
hb_script_to_iso15924_tag (hb_script_t script);
hb_direction_t
HB_EXTERN hb_direction_t
hb_script_get_horizontal_direction (hb_script_t script);

View File

@ -176,6 +176,43 @@ _hb_coretext_shaper_font_data_create (hb_font_t *font)
return NULL;
}
/* Create font copy with cascade list that has LastResort first; this speeds up CoreText
* font fallback which we don't need anyway. */
{
// TODO Handle allocation failures?
CTFontDescriptorRef last_resort = CTFontDescriptorCreateWithNameAndSize(CFSTR("LastResort"), 0);
CFArrayRef cascade_list = CFArrayCreate (kCFAllocatorDefault,
(const void **) &last_resort,
1,
&kCFTypeArrayCallBacks);
CFRelease (last_resort);
CFDictionaryRef attributes = CFDictionaryCreate (kCFAllocatorDefault,
(const void **) &kCTFontCascadeListAttribute,
(const void **) &cascade_list,
1,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
CFRelease (cascade_list);
CTFontDescriptorRef new_font_desc = CTFontDescriptorCreateWithAttributes (attributes);
CFRelease (attributes);
CTFontRef new_ct_font = CTFontCreateCopyWithAttributes (data->ct_font, 0.0, NULL, new_font_desc);
if (new_ct_font)
{
CFRelease (data->ct_font);
data->ct_font = new_ct_font;
}
else
DEBUG_MSG (CORETEXT, font, "Font copy with empty cascade list failed");
}
if (unlikely (!data->ct_font)) {
DEBUG_MSG (CORETEXT, font, "Font CTFontCreateWithGraphicsFont() failed");
free (data);
return NULL;
}
return data;
}
@ -693,7 +730,6 @@ resize_and_retry:
scratch += old_scratch_used;
scratch_size -= old_scratch_used;
}
retry:
{
string_ref = CFStringCreateWithCharactersNoCopy (NULL,
pchars, chars_len,
@ -848,11 +884,9 @@ retry:
* However, even that wouldn't work if we were passed in the CGFont to
* begin with.
*
* Webkit uses a slightly different approach: it installs LastResort
* as fallback chain, and then checks PS name of used font against
* LastResort. That one is safe for any font except for LastResort,
* as opposed to ours, which can fail if we are using any uninstalled
* font that has the same name as an installed font.
* We might switch to checking PS name against "LastResort". That would
* be safe for all fonts except for those named "Last Resort". Might be
* better than what we have right now.
*
* See: http://github.com/behdad/harfbuzz/pull/36
*/
@ -1129,10 +1163,6 @@ fail:
* AAT shaper
*/
HB_SHAPER_DATA_ENSURE_DECLARE(coretext_aat, face)
HB_SHAPER_DATA_ENSURE_DECLARE(coretext_aat, font)
/*
* shaper face data
*/

View File

@ -44,14 +44,14 @@ HB_BEGIN_DECLS
#define HB_CORETEXT_TAG_MORX HB_TAG('m','o','r','x')
hb_face_t *
HB_EXTERN hb_face_t *
hb_coretext_face_create (CGFontRef cg_font);
CGFontRef
HB_EXTERN CGFontRef
hb_coretext_face_get_cg_font (hb_face_t *face);
CTFontRef
HB_EXTERN CTFontRef
hb_coretext_font_get_ct_font (hb_font_t *font);

View File

@ -0,0 +1,827 @@
/*
* Copyright © 2015 Ebrahim Byagowi
*
* 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.
*/
#define HB_SHAPER directwrite
#include "hb-shaper-impl-private.hh"
#include <dwrite.h>
#include "hb-directwrite.h"
#include "hb-open-file-private.hh"
#include "hb-ot-name-table.hh"
#include "hb-ot-tag.h"
#ifndef HB_DEBUG_DIRECTWRITE
#define HB_DEBUG_DIRECTWRITE (HB_DEBUG+0)
#endif
HB_SHAPER_DATA_ENSURE_DECLARE(directwrite, face)
HB_SHAPER_DATA_ENSURE_DECLARE(directwrite, font)
/*
* shaper face data
*/
struct hb_directwrite_shaper_face_data_t {
HANDLE fh;
wchar_t face_name[LF_FACESIZE];
};
/* face_name should point to a wchar_t[LF_FACESIZE] object. */
static void
_hb_generate_unique_face_name(wchar_t *face_name, unsigned int *plen)
{
/* We'll create a private name for the font from a UUID using a simple,
* somewhat base64-like encoding scheme */
const char *enc = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-";
UUID id;
UuidCreate ((UUID*)&id);
ASSERT_STATIC (2 + 3 * (16 / 2) < LF_FACESIZE);
unsigned int name_str_len = 0;
face_name[name_str_len++] = 'F';
face_name[name_str_len++] = '_';
unsigned char *p = (unsigned char *)&id;
for (unsigned int i = 0; i < 16; i += 2)
{
/* Spread the 16 bits from two bytes of the UUID across three chars of face_name,
* using the bits in groups of 5,5,6 to select chars from enc.
* This will generate 24 characters; with the 'F_' prefix we already provided,
* the name will be 26 chars (plus the NUL terminator), so will always fit within
* face_name (LF_FACESIZE = 32). */
face_name[name_str_len++] = enc[p[i] >> 3];
face_name[name_str_len++] = enc[((p[i] << 2) | (p[i + 1] >> 6)) & 0x1f];
face_name[name_str_len++] = enc[p[i + 1] & 0x3f];
}
face_name[name_str_len] = 0;
if (plen)
*plen = name_str_len;
}
/* Destroys blob. */
static hb_blob_t *
_hb_rename_font(hb_blob_t *blob, wchar_t *new_name)
{
/* Create a copy of the font data, with the 'name' table replaced by a
* table that names the font with our private F_* name created above.
* For simplicity, we just append a new 'name' table and update the
* sfnt directory; the original table is left in place, but unused.
*
* The new table will contain just 5 name IDs: family, style, unique,
* full, PS. All of them point to the same name data with our unique name.
*/
blob = OT::Sanitizer<OT::OpenTypeFontFile>::sanitize (blob);
unsigned int length, new_length, name_str_len;
const char *orig_sfnt_data = hb_blob_get_data (blob, &length);
_hb_generate_unique_face_name (new_name, &name_str_len);
static const uint16_t name_IDs[] = { 1, 2, 3, 4, 6 };
unsigned int name_table_length = OT::name::min_size +
ARRAY_LENGTH(name_IDs) * OT::NameRecord::static_size +
name_str_len * 2; /* for name data in UTF16BE form */
unsigned int name_table_offset = (length + 3) & ~3;
new_length = name_table_offset + ((name_table_length + 3) & ~3);
void *new_sfnt_data = calloc(1, new_length);
if (!new_sfnt_data)
{
hb_blob_destroy (blob);
return NULL;
}
memcpy(new_sfnt_data, orig_sfnt_data, length);
OT::name &name = OT::StructAtOffset<OT::name> (new_sfnt_data, name_table_offset);
name.format.set (0);
name.count.set (ARRAY_LENGTH (name_IDs));
name.stringOffset.set (name.get_size());
for (unsigned int i = 0; i < ARRAY_LENGTH (name_IDs); i++)
{
OT::NameRecord &record = name.nameRecord[i];
record.platformID.set(3);
record.encodingID.set(1);
record.languageID.set(0x0409u); /* English */
record.nameID.set(name_IDs[i]);
record.length.set(name_str_len * 2);
record.offset.set(0);
}
/* Copy string data from new_name, converting wchar_t to UTF16BE. */
unsigned char *p = &OT::StructAfter<unsigned char>(name);
for (unsigned int i = 0; i < name_str_len; i++)
{
*p++ = new_name[i] >> 8;
*p++ = new_name[i] & 0xff;
}
/* Adjust name table entry to point to new name table */
const OT::OpenTypeFontFile &file = *(OT::OpenTypeFontFile *) (new_sfnt_data);
unsigned int face_count = file.get_face_count ();
for (unsigned int face_index = 0; face_index < face_count; face_index++)
{
/* Note: doing multiple edits (ie. TTC) can be unsafe. There may be
* toe-stepping. But we don't really care. */
const OT::OpenTypeFontFace &face = file.get_face (face_index);
unsigned int index;
if (face.find_table_index (HB_OT_TAG_name, &index))
{
OT::TableRecord &record = const_cast<OT::TableRecord &> (face.get_table (index));
record.checkSum.set_for_data (&name, name_table_length);
record.offset.set (name_table_offset);
record.length.set (name_table_length);
}
else if (face_index == 0) /* Fail if first face doesn't have 'name' table. */
{
free (new_sfnt_data);
hb_blob_destroy (blob);
return NULL;
}
}
/* The checkSumAdjustment field in the 'head' table is now wrong,
* but that doesn't actually seem to cause any problems so we don't
* bother. */
hb_blob_destroy (blob);
return hb_blob_create ((const char *)new_sfnt_data, new_length,
HB_MEMORY_MODE_WRITABLE, NULL, free);
}
hb_directwrite_shaper_face_data_t *
_hb_directwrite_shaper_face_data_create(hb_face_t *face)
{
hb_directwrite_shaper_face_data_t *data = (hb_directwrite_shaper_face_data_t *)calloc(1, sizeof (hb_directwrite_shaper_face_data_t));
if (unlikely (!data))
return NULL;
hb_blob_t *blob = hb_face_reference_blob (face);
if (unlikely (!hb_blob_get_length (blob)))
DEBUG_MSG(DIRECTWRITE, face, "Face has empty blob");
blob = _hb_rename_font (blob, data->face_name);
if (unlikely (!blob))
{
free(data);
return NULL;
}
DWORD num_fonts_installed;
data->fh = AddFontMemResourceEx ((void *)hb_blob_get_data(blob, NULL),
hb_blob_get_length (blob),
0, &num_fonts_installed);
if (unlikely (!data->fh))
{
DEBUG_MSG (DIRECTWRITE, face, "Face AddFontMemResourceEx() failed");
free (data);
return NULL;
}
return data;
}
void
_hb_directwrite_shaper_face_data_destroy(hb_directwrite_shaper_face_data_t *data)
{
RemoveFontMemResourceEx(data->fh);
free(data);
}
/*
* shaper font data
*/
struct hb_directwrite_shaper_font_data_t {
HDC hdc;
LOGFONTW log_font;
HFONT hfont;
};
static bool
populate_log_font (LOGFONTW *lf,
hb_font_t *font)
{
memset (lf, 0, sizeof (*lf));
lf->lfHeight = -font->y_scale;
lf->lfCharSet = DEFAULT_CHARSET;
hb_face_t *face = font->face;
hb_directwrite_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
memcpy (lf->lfFaceName, face_data->face_name, sizeof (lf->lfFaceName));
return true;
}
hb_directwrite_shaper_font_data_t *
_hb_directwrite_shaper_font_data_create (hb_font_t *font)
{
if (unlikely (!hb_directwrite_shaper_face_data_ensure (font->face))) return NULL;
hb_directwrite_shaper_font_data_t *data = (hb_directwrite_shaper_font_data_t *) calloc (1, sizeof (hb_directwrite_shaper_font_data_t));
if (unlikely (!data))
return NULL;
data->hdc = GetDC (NULL);
if (unlikely (!populate_log_font (&data->log_font, font))) {
DEBUG_MSG (DIRECTWRITE, font, "Font populate_log_font() failed");
_hb_directwrite_shaper_font_data_destroy (data);
return NULL;
}
data->hfont = CreateFontIndirectW (&data->log_font);
if (unlikely (!data->hfont)) {
DEBUG_MSG (DIRECTWRITE, font, "Font CreateFontIndirectW() failed");
_hb_directwrite_shaper_font_data_destroy (data);
return NULL;
}
if (!SelectObject (data->hdc, data->hfont)) {
DEBUG_MSG (DIRECTWRITE, font, "Font SelectObject() failed");
_hb_directwrite_shaper_font_data_destroy (data);
return NULL;
}
return data;
}
void
_hb_directwrite_shaper_font_data_destroy (hb_directwrite_shaper_font_data_t *data)
{
if (data->hdc)
ReleaseDC (NULL, data->hdc);
if (data->hfont)
DeleteObject (data->hfont);
free (data);
}
LOGFONTW *
hb_directwrite_font_get_logfontw (hb_font_t *font)
{
if (unlikely (!hb_directwrite_shaper_font_data_ensure (font))) return NULL;
hb_directwrite_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
return &font_data->log_font;
}
HFONT
hb_directwrite_font_get_hfont (hb_font_t *font)
{
if (unlikely (!hb_directwrite_shaper_font_data_ensure (font))) return NULL;
hb_directwrite_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
return font_data->hfont;
}
/*
* shaper shape_plan data
*/
struct hb_directwrite_shaper_shape_plan_data_t {};
hb_directwrite_shaper_shape_plan_data_t *
_hb_directwrite_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED,
const hb_feature_t *user_features HB_UNUSED,
unsigned int num_user_features HB_UNUSED)
{
return (hb_directwrite_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
}
void
_hb_directwrite_shaper_shape_plan_data_destroy (hb_directwrite_shaper_shape_plan_data_t *data HB_UNUSED)
{
}
// Most of here TextAnalysis is originally written by Bas Schouten for Mozilla project
// but now is relicensed to MIT for HarfBuzz use
class TextAnalysis
: public IDWriteTextAnalysisSource, public IDWriteTextAnalysisSink
{
public:
IFACEMETHOD(QueryInterface)(IID const& iid, OUT void** ppObject) { return S_OK; }
IFACEMETHOD_(ULONG, AddRef)() { return 1; }
IFACEMETHOD_(ULONG, Release)() { return 1; }
// A single contiguous run of characters containing the same analysis
// results.
struct Run
{
UINT32 mTextStart; // starting text position of this run
UINT32 mTextLength; // number of contiguous code units covered
UINT32 mGlyphStart; // starting glyph in the glyphs array
UINT32 mGlyphCount; // number of glyphs associated with this run of
// text
DWRITE_SCRIPT_ANALYSIS mScript;
UINT8 mBidiLevel;
bool mIsSideways;
inline bool ContainsTextPosition(UINT32 aTextPosition) const
{
return aTextPosition >= mTextStart
&& aTextPosition < mTextStart + mTextLength;
}
Run *nextRun;
};
public:
TextAnalysis(const wchar_t* text,
UINT32 textLength,
const wchar_t* localeName,
DWRITE_READING_DIRECTION readingDirection)
: mText(text)
, mTextLength(textLength)
, mLocaleName(localeName)
, mReadingDirection(readingDirection)
, mCurrentRun(NULL) { };
~TextAnalysis() {
// delete runs, except mRunHead which is part of the TextAnalysis object
for (Run *run = mRunHead.nextRun; run;) {
Run *origRun = run;
run = run->nextRun;
delete origRun;
}
}
STDMETHODIMP GenerateResults(IDWriteTextAnalyzer* textAnalyzer,
Run **runHead) {
// Analyzes the text using the script analyzer and returns
// the result as a series of runs.
HRESULT hr = S_OK;
// Initially start out with one result that covers the entire range.
// This result will be subdivided by the analysis processes.
mRunHead.mTextStart = 0;
mRunHead.mTextLength = mTextLength;
mRunHead.mBidiLevel =
(mReadingDirection == DWRITE_READING_DIRECTION_RIGHT_TO_LEFT);
mRunHead.nextRun = NULL;
mCurrentRun = &mRunHead;
// Call each of the analyzers in sequence, recording their results.
if (SUCCEEDED(hr = textAnalyzer->AnalyzeScript(this,
0,
mTextLength,
this))) {
*runHead = &mRunHead;
}
return hr;
}
// IDWriteTextAnalysisSource implementation
IFACEMETHODIMP GetTextAtPosition(UINT32 textPosition,
OUT WCHAR const** textString,
OUT UINT32* textLength)
{
if (textPosition >= mTextLength) {
// No text at this position, valid query though.
*textString = NULL;
*textLength = 0;
}
else {
*textString = mText + textPosition;
*textLength = mTextLength - textPosition;
}
return S_OK;
}
IFACEMETHODIMP GetTextBeforePosition(UINT32 textPosition,
OUT WCHAR const** textString,
OUT UINT32* textLength)
{
if (textPosition == 0 || textPosition > mTextLength) {
// Either there is no text before here (== 0), or this
// is an invalid position. The query is considered valid thouh.
*textString = NULL;
*textLength = 0;
}
else {
*textString = mText;
*textLength = textPosition;
}
return S_OK;
}
IFACEMETHODIMP_(DWRITE_READING_DIRECTION)
GetParagraphReadingDirection() { return mReadingDirection; }
IFACEMETHODIMP GetLocaleName(UINT32 textPosition,
UINT32* textLength,
WCHAR const** localeName) {
return S_OK;
}
IFACEMETHODIMP
GetNumberSubstitution(UINT32 textPosition,
OUT UINT32* textLength,
OUT IDWriteNumberSubstitution** numberSubstitution)
{
// We do not support number substitution.
*numberSubstitution = NULL;
*textLength = mTextLength - textPosition;
return S_OK;
}
// IDWriteTextAnalysisSink implementation
IFACEMETHODIMP
SetScriptAnalysis(UINT32 textPosition,
UINT32 textLength,
DWRITE_SCRIPT_ANALYSIS const* scriptAnalysis)
{
SetCurrentRun(textPosition);
SplitCurrentRun(textPosition);
while (textLength > 0) {
Run *run = FetchNextRun(&textLength);
run->mScript = *scriptAnalysis;
}
return S_OK;
}
IFACEMETHODIMP
SetLineBreakpoints(UINT32 textPosition,
UINT32 textLength,
const DWRITE_LINE_BREAKPOINT* lineBreakpoints) { return S_OK; }
IFACEMETHODIMP SetBidiLevel(UINT32 textPosition,
UINT32 textLength,
UINT8 explicitLevel,
UINT8 resolvedLevel) { return S_OK; }
IFACEMETHODIMP
SetNumberSubstitution(UINT32 textPosition,
UINT32 textLength,
IDWriteNumberSubstitution* numberSubstitution) { return S_OK; }
protected:
Run *FetchNextRun(IN OUT UINT32* textLength)
{
// Used by the sink setters, this returns a reference to the next run.
// Position and length are adjusted to now point after the current run
// being returned.
Run *origRun = mCurrentRun;
// Split the tail if needed (the length remaining is less than the
// current run's size).
if (*textLength < mCurrentRun->mTextLength) {
SplitCurrentRun(mCurrentRun->mTextStart + *textLength);
}
else {
// Just advance the current run.
mCurrentRun = mCurrentRun->nextRun;
}
*textLength -= origRun->mTextLength;
// Return a reference to the run that was just current.
return origRun;
}
void SetCurrentRun(UINT32 textPosition)
{
// Move the current run to the given position.
// Since the analyzers generally return results in a forward manner,
// this will usually just return early. If not, find the
// corresponding run for the text position.
if (mCurrentRun && mCurrentRun->ContainsTextPosition(textPosition)) {
return;
}
for (Run *run = &mRunHead; run; run = run->nextRun) {
if (run->ContainsTextPosition(textPosition)) {
mCurrentRun = run;
return;
}
}
//NS_NOTREACHED("We should always be able to find the text position in one \
// of our runs");
}
void SplitCurrentRun(UINT32 splitPosition)
{
if (!mCurrentRun) {
//NS_ASSERTION(false, "SplitCurrentRun called without current run.");
// Shouldn't be calling this when no current run is set!
return;
}
// Split the current run.
if (splitPosition <= mCurrentRun->mTextStart) {
// No need to split, already the start of a run
// or before it. Usually the first.
return;
}
Run *newRun = new Run;
*newRun = *mCurrentRun;
// Insert the new run in our linked list.
newRun->nextRun = mCurrentRun->nextRun;
mCurrentRun->nextRun = newRun;
// Adjust runs' text positions and lengths.
UINT32 splitPoint = splitPosition - mCurrentRun->mTextStart;
newRun->mTextStart += splitPoint;
newRun->mTextLength -= splitPoint;
mCurrentRun->mTextLength = splitPoint;
mCurrentRun = newRun;
}
protected:
// Input
// (weak references are fine here, since this class is a transient
// stack-based helper that doesn't need to copy data)
UINT32 mTextLength;
const WCHAR* mText;
const WCHAR* mLocaleName;
DWRITE_READING_DIRECTION mReadingDirection;
// Current processing state.
Run *mCurrentRun;
// Output is a list of runs starting here
Run mRunHead;
};
/*
* shaper
*/
hb_bool_t
_hb_directwrite_shape(hb_shape_plan_t *shape_plan,
hb_font_t *font,
hb_buffer_t *buffer,
const hb_feature_t *features,
unsigned int num_features)
{
hb_face_t *face = font->face;
hb_directwrite_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
hb_directwrite_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
// factory probably should be cached
IDWriteFactory* dwriteFactory;
DWriteCreateFactory(
DWRITE_FACTORY_TYPE_SHARED,
__uuidof(IDWriteFactory),
reinterpret_cast<IUnknown**>(&dwriteFactory)
);
IDWriteGdiInterop *gdiInterop;
dwriteFactory->GetGdiInterop (&gdiInterop);
IDWriteFontFace* fontFace;
gdiInterop->CreateFontFaceFromHdc (font_data->hdc, &fontFace);
IDWriteTextAnalyzer* analyzer;
dwriteFactory->CreateTextAnalyzer (&analyzer);
unsigned int scratch_size;
hb_buffer_t::scratch_buffer_t *scratch = buffer->get_scratch_buffer (&scratch_size);
#define ALLOCATE_ARRAY(Type, name, len) \
Type *name = (Type *) scratch; \
{ \
unsigned int _consumed = DIV_CEIL ((len) * sizeof (Type), sizeof (*scratch)); \
assert (_consumed <= scratch_size); \
scratch += _consumed; \
scratch_size -= _consumed; \
}
#define utf16_index() var1.u32
ALLOCATE_ARRAY(WCHAR, pchars, buffer->len * 2);
unsigned int chars_len = 0;
for (unsigned int i = 0; i < buffer->len; i++)
{
hb_codepoint_t c = buffer->info[i].codepoint;
buffer->info[i].utf16_index() = chars_len;
if (likely(c <= 0xFFFFu))
pchars[chars_len++] = c;
else if (unlikely(c > 0x10FFFFu))
pchars[chars_len++] = 0xFFFDu;
else {
pchars[chars_len++] = 0xD800u + ((c - 0x10000u) >> 10);
pchars[chars_len++] = 0xDC00u + ((c - 0x10000u) & ((1 << 10) - 1));
}
}
ALLOCATE_ARRAY(WORD, log_clusters, chars_len);
if (num_features)
{
/* Need log_clusters to assign features. */
chars_len = 0;
for (unsigned int i = 0; i < buffer->len; i++)
{
hb_codepoint_t c = buffer->info[i].codepoint;
unsigned int cluster = buffer->info[i].cluster;
log_clusters[chars_len++] = cluster;
if (hb_in_range(c, 0x10000u, 0x10FFFFu))
log_clusters[chars_len++] = cluster; /* Surrogates. */
}
}
HRESULT hr;
// TODO: Handle TEST_DISABLE_OPTIONAL_LIGATURES
DWRITE_READING_DIRECTION readingDirection = buffer->props.direction ?
DWRITE_READING_DIRECTION_RIGHT_TO_LEFT :
DWRITE_READING_DIRECTION_LEFT_TO_RIGHT;
/*
* There's an internal 16-bit limit on some things inside the analyzer,
* but we never attempt to shape a word longer than 64K characters
* in a single gfxShapedWord, so we cannot exceed that limit.
*/
UINT32 length = buffer->len;
TextAnalysis analysis(pchars, length, NULL, readingDirection);
TextAnalysis::Run *runHead;
hr = analysis.GenerateResults(analyzer, &runHead);
if (FAILED(hr)) {
//NS_WARNING("Analyzer failed to generate results.");
return false;
}
UINT32 maxGlyphs = 3 * length / 2 + 16;
#define INITIAL_GLYPH_SIZE 400
UINT16* clusters = (UINT16*)malloc(INITIAL_GLYPH_SIZE * sizeof(UINT16));
UINT16* glyphs = (UINT16*)malloc(INITIAL_GLYPH_SIZE * sizeof(UINT16));
DWRITE_SHAPING_TEXT_PROPERTIES* textProperties = (DWRITE_SHAPING_TEXT_PROPERTIES*)
malloc(INITIAL_GLYPH_SIZE * sizeof(DWRITE_SHAPING_TEXT_PROPERTIES));
DWRITE_SHAPING_GLYPH_PROPERTIES* glyphProperties = (DWRITE_SHAPING_GLYPH_PROPERTIES*)
malloc(INITIAL_GLYPH_SIZE * sizeof(DWRITE_SHAPING_GLYPH_PROPERTIES));
UINT32 actualGlyphs;
bool backward = HB_DIRECTION_IS_BACKWARD(buffer->props.direction);
wchar_t lang[4];
mbstowcs(lang, hb_language_to_string(buffer->props.language), 4);
hr = analyzer->GetGlyphs(pchars, length,
fontFace, FALSE,
buffer->props.direction,
&runHead->mScript, (const wchar_t*)lang, NULL, NULL, NULL, 0,
maxGlyphs, clusters, textProperties,
glyphs, glyphProperties, &actualGlyphs);
if (hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) {
free(clusters);
free(glyphs);
free(textProperties);
free(glyphProperties);
clusters = (UINT16*)malloc(INITIAL_GLYPH_SIZE * sizeof(UINT16));
glyphs = (UINT16*)malloc(INITIAL_GLYPH_SIZE * sizeof(UINT16));
textProperties = (DWRITE_SHAPING_TEXT_PROPERTIES*)
malloc(INITIAL_GLYPH_SIZE * sizeof(DWRITE_SHAPING_TEXT_PROPERTIES));
glyphProperties = (DWRITE_SHAPING_GLYPH_PROPERTIES*)
malloc(INITIAL_GLYPH_SIZE * sizeof(DWRITE_SHAPING_GLYPH_PROPERTIES));
hr = analyzer->GetGlyphs(pchars, length,
fontFace, FALSE,
buffer->props.direction,
&runHead->mScript, (const wchar_t*)lang, NULL, NULL, NULL, 0,
maxGlyphs, clusters, textProperties,
glyphs, glyphProperties, &actualGlyphs);
}
if (FAILED(hr)) {
//NS_WARNING("Analyzer failed to get glyphs.");
return false;
}
FLOAT advances[400];
DWRITE_GLYPH_OFFSET offsets[400];
/* The -2 in the following is to compensate for possible
* alignment needed after the WORD array. sizeof(WORD) == 2. */
unsigned int glyphs_size = (scratch_size * sizeof (int)-2)
/ (sizeof (WORD) +
4 + // sizeof (SCRIPT_GLYPHPROP) +
sizeof (int) +
8 + // sizeof (GOFFSET) +
sizeof (uint32_t));
ALLOCATE_ARRAY(uint32_t, vis_clusters, glyphs_size);
#undef ALLOCATE_ARRAY
hr = analyzer->GetGlyphPlacements(pchars,
clusters,
textProperties,
length,
glyphs,
glyphProperties,
actualGlyphs,
fontFace,
face->get_upem(),
FALSE,
FALSE,
&runHead->mScript,
NULL,
NULL,
NULL,
0,
advances,
offsets);
if (FAILED(hr)) {
//NS_WARNING("Analyzer failed to get glyph placements.");
return false;
}
unsigned int glyphs_len = actualGlyphs;
/* Ok, we've got everything we need, now compose output buffer,
* very, *very*, carefully! */
/* Calculate visual-clusters. That's what we ship. */
for (unsigned int i = 0; i < glyphs_len; i++)
vis_clusters[i] = -1;
for (unsigned int i = 0; i < buffer->len; i++) {
uint32_t *p = &vis_clusters[log_clusters[buffer->info[i].utf16_index()]];
//*p = MIN (*p, buffer->info[i].cluster);
}
for (unsigned int i = 1; i < glyphs_len; i++)
if (vis_clusters[i] == -1)
vis_clusters[i] = vis_clusters[i - 1];
#undef utf16_index
//if (unlikely (!buffer->ensure (glyphs_len)))
// FAIL ("Buffer in error");
#undef FAIL
/* Set glyph infos */
buffer->len = 0;
for (unsigned int i = 0; i < glyphs_len; i++)
{
hb_glyph_info_t *info = &buffer->info[buffer->len++];
info->codepoint = glyphs[i];
info->cluster = vis_clusters[i];
/* The rest is crap. Let's store position info there for now. */
info->mask = advances[i];
info->var1.u32 = offsets[i].ascenderOffset;
info->var2.u32 = -offsets[i].advanceOffset;
}
free(clusters);
free(glyphs);
free(textProperties);
free(glyphProperties);
/* Set glyph positions */
buffer->clear_positions ();
for (unsigned int i = 0; i < glyphs_len; i++)
{
hb_glyph_info_t *info = &buffer->info[i];
hb_glyph_position_t *pos = &buffer->pos[i];
/* TODO vertical */
pos->x_advance = info->mask;
pos->x_offset = backward ? -info->var1.u32 : info->var1.u32;
pos->y_offset = info->var2.u32;
}
if (backward)
hb_buffer_reverse (buffer);
/* Wow, done! */
return true;
}

View File

@ -0,0 +1,34 @@
/*
* Copyright © 2015 Ebrahim Byagowi
*
* 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.
*/
#ifndef HB_DIRECTWRITE_H
#define HB_DIRECTWRITE_H
#include "hb.h"
HB_BEGIN_DECLS
HB_END_DECLS
#endif /* HB_UNISCRIBE_H */

View File

@ -43,28 +43,28 @@ HB_BEGIN_DECLS
typedef struct hb_face_t hb_face_t;
hb_face_t *
HB_EXTERN hb_face_t *
hb_face_create (hb_blob_t *blob,
unsigned int index);
typedef hb_blob_t * (*hb_reference_table_func_t) (hb_face_t *face, hb_tag_t tag, void *user_data);
/* calls destroy() when not needing user_data anymore */
hb_face_t *
HB_EXTERN hb_face_t *
hb_face_create_for_tables (hb_reference_table_func_t reference_table_func,
void *user_data,
hb_destroy_func_t destroy);
hb_face_t *
HB_EXTERN hb_face_t *
hb_face_get_empty (void);
hb_face_t *
HB_EXTERN hb_face_t *
hb_face_reference (hb_face_t *face);
void
HB_EXTERN void
hb_face_destroy (hb_face_t *face);
hb_bool_t
HB_EXTERN hb_bool_t
hb_face_set_user_data (hb_face_t *face,
hb_user_data_key_t *key,
void * data,
@ -72,43 +72,43 @@ hb_face_set_user_data (hb_face_t *face,
hb_bool_t replace);
void *
HB_EXTERN void *
hb_face_get_user_data (hb_face_t *face,
hb_user_data_key_t *key);
void
HB_EXTERN void
hb_face_make_immutable (hb_face_t *face);
hb_bool_t
HB_EXTERN hb_bool_t
hb_face_is_immutable (hb_face_t *face);
hb_blob_t *
HB_EXTERN hb_blob_t *
hb_face_reference_table (hb_face_t *face,
hb_tag_t tag);
hb_blob_t *
HB_EXTERN hb_blob_t *
hb_face_reference_blob (hb_face_t *face);
void
HB_EXTERN void
hb_face_set_index (hb_face_t *face,
unsigned int index);
unsigned int
HB_EXTERN unsigned int
hb_face_get_index (hb_face_t *face);
void
HB_EXTERN void
hb_face_set_upem (hb_face_t *face,
unsigned int upem);
unsigned int
HB_EXTERN unsigned int
hb_face_get_upem (hb_face_t *face);
void
HB_EXTERN void
hb_face_set_glyph_count (hb_face_t *face,
unsigned int glyph_count);
unsigned int
HB_EXTERN unsigned int
hb_face_get_glyph_count (hb_face_t *face);

View File

@ -106,7 +106,7 @@ _hb_fallback_shape (hb_shape_plan_t *shape_plan HB_UNUSED,
*/
hb_codepoint_t space;
bool has_space = font->get_glyph (' ', 0, &space);
bool has_space = (bool) font->get_glyph (' ', 0, &space);
buffer->clear_positions ();

View File

@ -42,6 +42,8 @@
*/
#define HB_FONT_FUNCS_IMPLEMENT_CALLBACKS \
HB_FONT_FUNC_IMPLEMENT (font_h_extents) \
HB_FONT_FUNC_IMPLEMENT (font_v_extents) \
HB_FONT_FUNC_IMPLEMENT (glyph) \
HB_FONT_FUNC_IMPLEMENT (glyph_h_advance) \
HB_FONT_FUNC_IMPLEMENT (glyph_v_advance) \
@ -80,7 +82,7 @@ struct hb_font_funcs_t {
HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_FONT_FUNC_IMPLEMENT
} f;
void (*array[]) (void);
void (*array[VAR]) (void);
} get;
};
@ -160,7 +162,22 @@ struct hb_font_t {
HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_FONT_FUNC_IMPLEMENT
inline hb_bool_t has_glyph (hb_codepoint_t unicode)
inline hb_bool_t get_font_h_extents (hb_font_extents_t *extents)
{
memset (extents, 0, sizeof (*extents));
return klass->get.f.font_h_extents (this, user_data,
extents,
klass->user_data.font_h_extents);
}
inline hb_bool_t get_font_v_extents (hb_font_extents_t *extents)
{
memset (extents, 0, sizeof (*extents));
return klass->get.f.font_v_extents (this, user_data,
extents,
klass->user_data.font_v_extents);
}
inline bool has_glyph (hb_codepoint_t unicode)
{
hb_codepoint_t glyph;
return get_glyph (unicode, 0, &glyph);
@ -265,6 +282,26 @@ struct hb_font_t {
/* A bit higher-level, and with fallback */
inline void get_extents_for_direction (hb_direction_t direction,
hb_font_extents_t *extents)
{
if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) {
if (!get_font_h_extents (extents))
{
extents->ascender = y_scale * .8;
extents->descender = y_scale - extents->ascender;
extents->line_gap = 0;
}
} else {
if (!get_font_v_extents (extents))
{
extents->ascender = x_scale / 2;
extents->descender = x_scale - extents->ascender;
extents->line_gap = 0;
}
}
}
inline void get_glyph_advance_for_direction (hb_codepoint_t glyph,
hb_direction_t direction,
hb_position_t *x, hb_position_t *y)
@ -284,7 +321,7 @@ struct hb_font_t {
{
*x = get_glyph_h_advance (glyph) / 2;
/* TODO use font_metrics.ascent */
/* TODO use font_extents.ascender */
*y = y_scale;
}

View File

@ -44,6 +44,54 @@
* hb_font_funcs_t
*/
static hb_bool_t
hb_font_get_font_h_extents_nil (hb_font_t *font,
void *font_data HB_UNUSED,
hb_font_extents_t *metrics,
void *user_data HB_UNUSED)
{
memset (metrics, 0, sizeof (*metrics));
return false;
}
static hb_bool_t
hb_font_get_font_h_extents_parent (hb_font_t *font,
void *font_data HB_UNUSED,
hb_font_extents_t *metrics,
void *user_data HB_UNUSED)
{
hb_bool_t ret = font->parent->get_font_h_extents (metrics);
if (ret) {
metrics->ascender = font->parent_scale_y_distance (metrics->ascender);
metrics->descender = font->parent_scale_y_distance (metrics->descender);
metrics->line_gap = font->parent_scale_y_distance (metrics->line_gap);
}
return ret;
}
static hb_bool_t
hb_font_get_font_v_extents_nil (hb_font_t *font,
void *font_data HB_UNUSED,
hb_font_extents_t *metrics,
void *user_data HB_UNUSED)
{
memset (metrics, 0, sizeof (*metrics));
return false;
}
static hb_bool_t
hb_font_get_font_v_extents_parent (hb_font_t *font,
void *font_data HB_UNUSED,
hb_font_extents_t *metrics,
void *user_data HB_UNUSED)
{
hb_bool_t ret = font->parent->get_font_v_extents (metrics);
if (ret) {
metrics->ascender = font->parent_scale_x_distance (metrics->ascender);
metrics->descender = font->parent_scale_x_distance (metrics->descender);
metrics->line_gap = font->parent_scale_x_distance (metrics->line_gap);
}
return ret;
}
static hb_bool_t
hb_font_get_glyph_nil (hb_font_t *font HB_UNUSED,
void *font_data HB_UNUSED,
@ -109,7 +157,7 @@ hb_font_get_glyph_h_origin_nil (hb_font_t *font HB_UNUSED,
void *user_data HB_UNUSED)
{
*x = *y = 0;
return false;
return true;
}
static hb_bool_t
hb_font_get_glyph_h_origin_parent (hb_font_t *font,
@ -280,7 +328,6 @@ hb_font_get_glyph_from_name_parent (hb_font_t *font,
return font->parent->get_glyph_from_name (name, len, glyph);
}
static const hb_font_funcs_t _hb_font_funcs_nil = {
HB_OBJECT_HEADER_STATIC,
@ -521,6 +568,42 @@ hb_font_t::has_func (unsigned int i)
/* Public getters */
/**
* hb_font_get_h_extents:
* @font: a font.
* @extents: (out):
*
*
*
* Return value:
*
* Since: 1.1.3
**/
hb_bool_t
hb_font_get_h_extents (hb_font_t *font,
hb_font_extents_t *extents)
{
return font->get_font_h_extents (extents);
}
/**
* hb_font_get_v_extents:
* @font: a font.
* @extents: (out):
*
*
*
* Return value:
*
* Since: 1.1.3
**/
hb_bool_t
hb_font_get_v_extents (hb_font_t *font,
hb_font_extents_t *extents)
{
return font->get_font_v_extents (extents);
}
/**
* hb_font_get_glyph:
* @font: a font.
@ -745,6 +828,23 @@ hb_font_get_glyph_from_name (hb_font_t *font,
/* A bit higher-level, and with fallback */
/**
* hb_font_get_extents_for_direction:
* @font: a font.
* @direction:
* @extents:
*
*
*
* Since: 1.1.3
**/
void
hb_font_get_extents_for_direction (hb_font_t *font,
hb_direction_t direction,
hb_font_extents_t *extents)
{
return font->get_extents_for_direction (direction, extents);
}
/**
* hb_font_get_glyph_advance_for_direction:
* @font: a font.

View File

@ -46,19 +46,19 @@ typedef struct hb_font_t hb_font_t;
typedef struct hb_font_funcs_t hb_font_funcs_t;
hb_font_funcs_t *
HB_EXTERN hb_font_funcs_t *
hb_font_funcs_create (void);
hb_font_funcs_t *
HB_EXTERN hb_font_funcs_t *
hb_font_funcs_get_empty (void);
hb_font_funcs_t *
HB_EXTERN hb_font_funcs_t *
hb_font_funcs_reference (hb_font_funcs_t *ffuncs);
void
HB_EXTERN void
hb_font_funcs_destroy (hb_font_funcs_t *ffuncs);
hb_bool_t
HB_EXTERN hb_bool_t
hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs,
hb_user_data_key_t *key,
void * data,
@ -66,19 +66,37 @@ hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs,
hb_bool_t replace);
void *
HB_EXTERN void *
hb_font_funcs_get_user_data (hb_font_funcs_t *ffuncs,
hb_user_data_key_t *key);
void
HB_EXTERN void
hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs);
hb_bool_t
HB_EXTERN hb_bool_t
hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs);
/* glyph extents */
/* font and glyph extents */
/* Note that typically ascender is positive and descender negative in coordinate systems that grow up. */
typedef struct hb_font_extents_t
{
hb_position_t ascender; /* typographic ascender. */
hb_position_t descender; /* typographic descender. */
hb_position_t line_gap; /* suggested line spacing gap. */
/*< private >*/
hb_position_t reserved9;
hb_position_t reserved8;
hb_position_t reserved7;
hb_position_t reserved6;
hb_position_t reserved5;
hb_position_t reserved4;
hb_position_t reserved3;
hb_position_t reserved2;
hb_position_t reserved1;
} hb_font_extents_t;
/* Note that height is negative in coordinate systems that grow up. */
typedef struct hb_glyph_extents_t
@ -89,9 +107,15 @@ typedef struct hb_glyph_extents_t
hb_position_t height; /* distance from top to bottom side. */
} hb_glyph_extents_t;
/* func types */
typedef hb_bool_t (*hb_font_get_font_extents_func_t) (hb_font_t *font, void *font_data,
hb_font_extents_t *metrics,
void *user_data);
typedef hb_font_get_font_extents_func_t hb_font_get_font_h_extents_func_t;
typedef hb_font_get_font_extents_func_t hb_font_get_font_v_extents_func_t;
typedef hb_bool_t (*hb_font_get_glyph_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t unicode, hb_codepoint_t variation_selector,
hb_codepoint_t *glyph,
@ -140,6 +164,38 @@ typedef hb_bool_t (*hb_font_get_glyph_from_name_func_t) (hb_font_t *font, void *
/* func setters */
/**
* hb_font_funcs_set_font_h_extents_func:
* @ffuncs: font functions.
* @func: (closure user_data) (destroy destroy) (scope notified):
* @user_data:
* @destroy:
*
*
*
* Since: 1.1.2
**/
HB_EXTERN void
hb_font_funcs_set_font_h_extents_func (hb_font_funcs_t *ffuncs,
hb_font_get_font_h_extents_func_t func,
void *user_data, hb_destroy_func_t destroy);
/**
* hb_font_funcs_set_font_v_extents_func:
* @ffuncs: font functions.
* @func: (closure user_data) (destroy destroy) (scope notified):
* @user_data:
* @destroy:
*
*
*
* Since: 1.1.2
**/
HB_EXTERN void
hb_font_funcs_set_font_v_extents_func (hb_font_funcs_t *ffuncs,
hb_font_get_font_v_extents_func_t func,
void *user_data, hb_destroy_func_t destroy);
/**
* hb_font_funcs_set_glyph_func:
* @ffuncs: font functions.
@ -151,7 +207,7 @@ typedef hb_bool_t (*hb_font_get_glyph_from_name_func_t) (hb_font_t *font, void *
*
* Since: 0.9.2
**/
void
HB_EXTERN void
hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_func_t func,
void *user_data, hb_destroy_func_t destroy);
@ -167,7 +223,7 @@ hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs,
*
* Since: 0.9.2
**/
void
HB_EXTERN 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);
@ -183,7 +239,7 @@ hb_font_funcs_set_glyph_h_advance_func (hb_font_funcs_t *ffuncs,
*
* Since: 0.9.2
**/
void
HB_EXTERN 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);
@ -199,7 +255,7 @@ hb_font_funcs_set_glyph_v_advance_func (hb_font_funcs_t *ffuncs,
*
* Since: 0.9.2
**/
void
HB_EXTERN 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);
@ -215,7 +271,7 @@ hb_font_funcs_set_glyph_h_origin_func (hb_font_funcs_t *ffuncs,
*
* Since: 0.9.2
**/
void
HB_EXTERN 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);
@ -231,7 +287,7 @@ hb_font_funcs_set_glyph_v_origin_func (hb_font_funcs_t *ffuncs,
*
* Since: 0.9.2
**/
void
HB_EXTERN 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);
@ -247,7 +303,7 @@ hb_font_funcs_set_glyph_h_kerning_func (hb_font_funcs_t *ffuncs,
*
* Since: 0.9.2
**/
void
HB_EXTERN 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);
@ -263,7 +319,7 @@ hb_font_funcs_set_glyph_v_kerning_func (hb_font_funcs_t *ffuncs,
*
* Since: 0.9.2
**/
void
HB_EXTERN 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);
@ -279,7 +335,7 @@ hb_font_funcs_set_glyph_extents_func (hb_font_funcs_t *ffuncs,
*
* Since: 0.9.2
**/
void
HB_EXTERN 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);
@ -295,7 +351,7 @@ hb_font_funcs_set_glyph_contour_point_func (hb_font_funcs_t *ffuncs,
*
* Since: 0.9.2
**/
void
HB_EXTERN void
hb_font_funcs_set_glyph_name_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_name_func_t func,
void *user_data, hb_destroy_func_t destroy);
@ -311,57 +367,63 @@ hb_font_funcs_set_glyph_name_func (hb_font_funcs_t *ffuncs,
*
* Since: 0.9.2
**/
void
HB_EXTERN void
hb_font_funcs_set_glyph_from_name_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_from_name_func_t func,
void *user_data, hb_destroy_func_t destroy);
/* func dispatch */
hb_bool_t
HB_EXTERN hb_bool_t
hb_font_get_h_extents (hb_font_t *font,
hb_font_extents_t *extents);
HB_EXTERN hb_bool_t
hb_font_get_v_extents (hb_font_t *font,
hb_font_extents_t *extents);
HB_EXTERN hb_bool_t
hb_font_get_glyph (hb_font_t *font,
hb_codepoint_t unicode, hb_codepoint_t variation_selector,
hb_codepoint_t *glyph);
hb_position_t
HB_EXTERN hb_position_t
hb_font_get_glyph_h_advance (hb_font_t *font,
hb_codepoint_t glyph);
hb_position_t
HB_EXTERN hb_position_t
hb_font_get_glyph_v_advance (hb_font_t *font,
hb_codepoint_t glyph);
hb_bool_t
HB_EXTERN hb_bool_t
hb_font_get_glyph_h_origin (hb_font_t *font,
hb_codepoint_t glyph,
hb_position_t *x, hb_position_t *y);
hb_bool_t
HB_EXTERN hb_bool_t
hb_font_get_glyph_v_origin (hb_font_t *font,
hb_codepoint_t glyph,
hb_position_t *x, hb_position_t *y);
hb_position_t
HB_EXTERN hb_position_t
hb_font_get_glyph_h_kerning (hb_font_t *font,
hb_codepoint_t left_glyph, hb_codepoint_t right_glyph);
hb_position_t
HB_EXTERN hb_position_t
hb_font_get_glyph_v_kerning (hb_font_t *font,
hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph);
hb_bool_t
HB_EXTERN hb_bool_t
hb_font_get_glyph_extents (hb_font_t *font,
hb_codepoint_t glyph,
hb_glyph_extents_t *extents);
hb_bool_t
HB_EXTERN hb_bool_t
hb_font_get_glyph_contour_point (hb_font_t *font,
hb_codepoint_t glyph, unsigned int point_index,
hb_position_t *x, hb_position_t *y);
hb_bool_t
HB_EXTERN hb_bool_t
hb_font_get_glyph_name (hb_font_t *font,
hb_codepoint_t glyph,
char *name, unsigned int size);
hb_bool_t
HB_EXTERN hb_bool_t
hb_font_get_glyph_from_name (hb_font_t *font,
const char *name, int len, /* -1 means nul-terminated */
hb_codepoint_t *glyph);
@ -369,52 +431,56 @@ hb_font_get_glyph_from_name (hb_font_t *font,
/* high-level funcs, with fallback */
void
HB_EXTERN void
hb_font_get_extents_for_direction (hb_font_t *font,
hb_direction_t direction,
hb_font_extents_t *extents);
HB_EXTERN void
hb_font_get_glyph_advance_for_direction (hb_font_t *font,
hb_codepoint_t glyph,
hb_direction_t direction,
hb_position_t *x, hb_position_t *y);
void
HB_EXTERN void
hb_font_get_glyph_origin_for_direction (hb_font_t *font,
hb_codepoint_t glyph,
hb_direction_t direction,
hb_position_t *x, hb_position_t *y);
void
HB_EXTERN void
hb_font_add_glyph_origin_for_direction (hb_font_t *font,
hb_codepoint_t glyph,
hb_direction_t direction,
hb_position_t *x, hb_position_t *y);
void
HB_EXTERN void
hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
hb_codepoint_t glyph,
hb_direction_t direction,
hb_position_t *x, hb_position_t *y);
void
HB_EXTERN void
hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
hb_direction_t direction,
hb_position_t *x, hb_position_t *y);
hb_bool_t
HB_EXTERN hb_bool_t
hb_font_get_glyph_extents_for_origin (hb_font_t *font,
hb_codepoint_t glyph,
hb_direction_t direction,
hb_glyph_extents_t *extents);
hb_bool_t
HB_EXTERN hb_bool_t
hb_font_get_glyph_contour_point_for_origin (hb_font_t *font,
hb_codepoint_t glyph, unsigned int point_index,
hb_direction_t direction,
hb_position_t *x, hb_position_t *y);
/* Generates gidDDD if glyph has no name. */
void
HB_EXTERN void
hb_font_glyph_to_string (hb_font_t *font,
hb_codepoint_t glyph,
char *s, unsigned int size);
/* Parses gidDDD and uniUUUU strings automatically. */
hb_bool_t
HB_EXTERN hb_bool_t
hb_font_glyph_from_string (hb_font_t *font,
const char *s, int len, /* -1 means nul-terminated */
hb_codepoint_t *glyph);
@ -426,22 +492,22 @@ hb_font_glyph_from_string (hb_font_t *font,
/* Fonts are very light-weight objects */
hb_font_t *
HB_EXTERN hb_font_t *
hb_font_create (hb_face_t *face);
hb_font_t *
HB_EXTERN hb_font_t *
hb_font_create_sub_font (hb_font_t *parent);
hb_font_t *
HB_EXTERN hb_font_t *
hb_font_get_empty (void);
hb_font_t *
HB_EXTERN hb_font_t *
hb_font_reference (hb_font_t *font);
void
HB_EXTERN void
hb_font_destroy (hb_font_t *font);
hb_bool_t
HB_EXTERN hb_bool_t
hb_font_set_user_data (hb_font_t *font,
hb_user_data_key_t *key,
void * data,
@ -449,46 +515,46 @@ hb_font_set_user_data (hb_font_t *font,
hb_bool_t replace);
void *
HB_EXTERN void *
hb_font_get_user_data (hb_font_t *font,
hb_user_data_key_t *key);
void
HB_EXTERN void
hb_font_make_immutable (hb_font_t *font);
hb_bool_t
HB_EXTERN hb_bool_t
hb_font_is_immutable (hb_font_t *font);
void
HB_EXTERN void
hb_font_set_parent (hb_font_t *font,
hb_font_t *parent);
hb_font_t *
HB_EXTERN hb_font_t *
hb_font_get_parent (hb_font_t *font);
hb_face_t *
HB_EXTERN hb_face_t *
hb_font_get_face (hb_font_t *font);
void
HB_EXTERN void
hb_font_set_funcs (hb_font_t *font,
hb_font_funcs_t *klass,
void *font_data,
hb_destroy_func_t destroy);
/* Be *very* careful with this function! */
void
HB_EXTERN void
hb_font_set_funcs_data (hb_font_t *font,
void *font_data,
hb_destroy_func_t destroy);
void
HB_EXTERN void
hb_font_set_scale (hb_font_t *font,
int x_scale,
int y_scale);
void
HB_EXTERN void
hb_font_get_scale (hb_font_t *font,
int *x_scale,
int *y_scale);
@ -496,12 +562,12 @@ hb_font_get_scale (hb_font_t *font,
/*
* A zero value means "no hinting in that direction"
*/
void
HB_EXTERN void
hb_font_set_ppem (hb_font_t *font,
unsigned int x_ppem,
unsigned int y_ppem);
void
HB_EXTERN void
hb_font_get_ppem (hb_font_t *font,
unsigned int *x_ppem,
unsigned int *y_ppem);

View File

@ -366,6 +366,25 @@ hb_ft_get_glyph_from_name (hb_font_t *font HB_UNUSED,
return *glyph != 0;
}
static hb_bool_t
hb_ft_get_font_h_extents (hb_font_t *font HB_UNUSED,
void *font_data,
hb_font_extents_t *metrics,
void *user_data HB_UNUSED)
{
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
FT_Face ft_face = ft_font->ft_face;
metrics->ascender = ft_face->size->metrics.ascender;
metrics->descender = ft_face->size->metrics.descender;
metrics->line_gap = ft_face->size->metrics.height - (ft_face->size->metrics.ascender - ft_face->size->metrics.descender);
if (font->y_scale < 0)
{
metrics->ascender = -metrics->ascender;
metrics->descender = -metrics->descender;
metrics->line_gap = -metrics->line_gap;
}
return true;
}
static hb_font_funcs_t *static_ft_funcs = NULL;
@ -387,6 +406,8 @@ retry:
{
funcs = hb_font_funcs_create ();
hb_font_funcs_set_font_h_extents_func (funcs, hb_ft_get_font_h_extents, NULL, NULL);
//hb_font_funcs_set_font_v_extents_func (funcs, hb_ft_get_font_v_extents, NULL, NULL);
hb_font_funcs_set_glyph_func (funcs, hb_ft_get_glyph, NULL, NULL);
hb_font_funcs_set_glyph_h_advance_func (funcs, hb_ft_get_glyph_h_advance, NULL, NULL);
hb_font_funcs_set_glyph_v_advance_func (funcs, hb_ft_get_glyph_v_advance, NULL, NULL);

View File

@ -59,7 +59,7 @@ HB_BEGIN_DECLS
* probably should use (the more recent) hb_ft_face_create_referenced()
* instead.
*/
hb_face_t *
HB_EXTERN hb_face_t *
hb_ft_face_create (FT_Face ft_face,
hb_destroy_func_t destroy);
@ -71,7 +71,7 @@ hb_ft_face_create (FT_Face ft_face,
* Client is still responsible for making sure that ft-face is destroyed
* after hb-face is.
*/
hb_face_t *
HB_EXTERN hb_face_t *
hb_ft_face_create_cached (FT_Face ft_face);
/* This version is like hb_ft_face_create(), except that it calls
@ -81,7 +81,7 @@ hb_ft_face_create_cached (FT_Face ft_face);
* This is the most convenient version to use. Use it unless you have
* very good reasons not to.
*/
hb_face_t *
HB_EXTERN hb_face_t *
hb_ft_face_create_referenced (FT_Face ft_face);
@ -98,26 +98,26 @@ hb_ft_face_create_referenced (FT_Face ft_face);
/* See notes on hb_ft_face_create(). Same issues re lifecycle-management
* apply here. Use hb_ft_font_create_referenced() if you can. */
hb_font_t *
HB_EXTERN hb_font_t *
hb_ft_font_create (FT_Face ft_face,
hb_destroy_func_t destroy);
/* See notes on hb_ft_face_create_referenced() re lifecycle-management
* issues. */
hb_font_t *
HB_EXTERN hb_font_t *
hb_ft_font_create_referenced (FT_Face ft_face);
FT_Face
HB_EXTERN FT_Face
hb_ft_font_get_face (hb_font_t *font);
void
HB_EXTERN void
hb_ft_font_set_load_flags (hb_font_t *font, int load_flags);
int
HB_EXTERN int
hb_ft_font_get_load_flags (hb_font_t *font);
/* Makes an hb_font_t use FreeType internally to implement font functions. */
void
HB_EXTERN void
hb_ft_font_set_funcs (hb_font_t *font);

View File

@ -383,6 +383,8 @@ hb_glib_get_unicode_funcs (void)
}
/**
* hb_glib_blob_create:
*
* Since: 0.9.38
**/
hb_blob_t *

Some files were not shown because too many files have changed in this diff Show More