mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-03-04 07:40:42 +00:00
Merge m-c to fx-team. a=merge
This commit is contained in:
commit
a6e049875d
2
CLOBBER
2
CLOBBER
@ -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
|
||||
|
@ -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. -->
|
||||
|
@ -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. -->
|
||||
|
@ -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. -->
|
||||
|
@ -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"/>
|
||||
|
@ -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. -->
|
||||
|
@ -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. -->
|
||||
|
@ -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. -->
|
||||
|
@ -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"/>
|
||||
|
@ -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. -->
|
||||
|
@ -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"
|
||||
}
|
||||
|
@ -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. -->
|
||||
|
@ -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. -->
|
||||
|
@ -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"/>
|
||||
|
@ -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">
|
||||
|
@ -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"
|
||||
;;
|
||||
|
@ -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',
|
||||
|
@ -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);
|
||||
|
@ -20,7 +20,6 @@ new
|
||||
algorithm
|
||||
atomic
|
||||
deque
|
||||
initializer_list
|
||||
ios
|
||||
iosfwd
|
||||
iostream
|
||||
|
@ -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
@ -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
|
||||
|
@ -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
|
||||
|
@ -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<>
|
||||
|
@ -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 {
|
||||
|
@ -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)));
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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")
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 \
|
||||
|
38
dom/cache/DBSchema.cpp
vendored
38
dom/cache/DBSchema.cpp
vendored
@ -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
|
||||
|
3
dom/cache/test/xpcshell/head.js
vendored
3
dom/cache/test/xpcshell/head.js
vendored
@ -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']);
|
||||
|
||||
|
BIN
dom/cache/test/xpcshell/schema_15_profile.zip
vendored
BIN
dom/cache/test/xpcshell/schema_15_profile.zip
vendored
Binary file not shown.
1
dom/cache/test/xpcshell/test_migration.js
vendored
1
dom/cache/test/xpcshell/test_migration.js
vendored
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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');
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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 = {
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -39,6 +39,7 @@ if CONFIG['MOZ_EME']:
|
||||
DIRS += ['agnostic/eme']
|
||||
|
||||
if CONFIG['MOZ_FFMPEG']:
|
||||
LOCAL_INCLUDES += ['/xpcom/build']
|
||||
EXPORTS += [
|
||||
'ffmpeg/FFmpegRuntimeLinker.h',
|
||||
]
|
||||
|
@ -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] () {
|
||||
|
@ -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();
|
||||
|
@ -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());
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -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))
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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>
|
||||
|
@ -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!
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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;
|
||||
|
||||
|
27
dom/webidl/RTCTrackEvent.webidl
Normal file
27
dom/webidl/RTCTrackEvent.webidl
Normal 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
|
||||
};
|
@ -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" };
|
||||
|
@ -837,6 +837,7 @@ if CONFIG['MOZ_WEBRTC']:
|
||||
'MediaStreamTrackEvent.webidl',
|
||||
'RTCDataChannelEvent.webidl',
|
||||
'RTCPeerConnectionIceEvent.webidl',
|
||||
'RTCTrackEvent.webidl',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_WEBSPEECH']:
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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',
|
||||
|
@ -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']
|
||||
|
@ -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 \
|
||||
|
@ -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
|
||||
|
@ -91,6 +91,7 @@ short = [{
|
||||
"Visarga": 'Vs',
|
||||
"Vowel": 'Vo',
|
||||
"Vowel_Dependent": 'M',
|
||||
"Consonant_Prefixed": 'CPrf',
|
||||
"Other": 'x',
|
||||
},{
|
||||
"Not_Applicable": 'x',
|
||||
|
@ -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. */
|
||||
|
@ -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);
|
||||
|
||||
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
@ -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
|
||||
* `<x_bearing,y_bearing,width,height>`
|
||||
*
|
||||
* ## 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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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);
|
||||
|
||||
|
||||
|
827
gfx/harfbuzz/src/hb-directwrite.cc
Normal file
827
gfx/harfbuzz/src/hb-directwrite.cc
Normal 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;
|
||||
}
|
34
gfx/harfbuzz/src/hb-directwrite.h
Normal file
34
gfx/harfbuzz/src/hb-directwrite.h
Normal 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 */
|
@ -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);
|
||||
|
||||
|
||||
|
@ -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 ();
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
||||
|
@ -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
Loading…
x
Reference in New Issue
Block a user