Compare commits
162
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4d5b1cc5d8 | ||
|
|
0e521f6302 | ||
|
|
9cacfcff57 | ||
|
|
21ad7adc90 | ||
|
|
9a29430751 | ||
|
|
481d4868b0 | ||
|
|
d148c11717 | ||
|
|
bc322e58f8 | ||
|
|
e48a6f26a5 | ||
|
|
d85edd01df | ||
|
|
296379d751 | ||
|
|
7ba9fc2801 | ||
|
|
a9ac8b390f | ||
|
|
71c0f8246c | ||
|
|
6cda35442f | ||
|
|
1dba423327 | ||
|
|
e2af0b28bf | ||
|
|
5ea9b7b80a | ||
|
|
b799e100ad | ||
|
|
1c500a6abb | ||
|
|
b909fccc92 | ||
|
|
abddee43b4 | ||
|
|
49d184e550 | ||
|
|
3e223cbfb4 | ||
|
|
dd9099a7d3 | ||
|
|
31558a1521 | ||
|
|
0e683bf699 | ||
|
|
6459dec5bb | ||
|
|
0e930fba3f | ||
|
|
3b683bbe59 | ||
|
|
0042e54c38 | ||
|
|
e75201f7d1 | ||
|
|
28c47723b2 | ||
|
|
3d872ff7b0 | ||
|
|
beb684c29e | ||
|
|
775588b75d | ||
|
|
8a2a5d837c | ||
|
|
8add755c81 | ||
|
|
257c64567e | ||
|
|
d0b61d4a68 | ||
|
|
3b5f50cc35 | ||
|
|
27c6a7f477 | ||
|
|
c65f84214e | ||
|
|
a317c65fd7 | ||
|
|
0ec35ce534 | ||
|
|
bf0c040722 | ||
|
|
ebadd51401 | ||
|
|
5ed0bf8b44 | ||
|
|
f877c1dba5 | ||
|
|
4c14f8f89b | ||
|
|
c119728965 | ||
|
|
fa55b9c2e8 | ||
|
|
16aba76fc5 | ||
|
|
995def99cd | ||
|
|
923e52789c | ||
|
|
22d945430b | ||
|
|
65d7d93760 | ||
|
|
dfd0ea4e8a | ||
|
|
12a49709cb | ||
|
|
2a70c8a6f0 | ||
|
|
1f639d78ca | ||
|
|
65e8245153 | ||
|
|
bce5dbad0b | ||
|
|
0b25b5f8db | ||
|
|
7345874098 | ||
|
|
edb82fd1c9 | ||
|
|
35ebdcac66 | ||
|
|
a095661e86 | ||
|
|
205a0d66bb | ||
|
|
54945a0808 | ||
|
|
84c1eedac6 | ||
|
|
ddf5d6256e | ||
|
|
0eae777fd0 | ||
|
|
b2594a4ace | ||
|
|
ce61835a81 | ||
|
|
30e29845c4 | ||
|
|
d8662c5dd9 | ||
|
|
8a2a9ead92 | ||
|
|
efdbd34b0b | ||
|
|
d2fa69f593 | ||
|
|
18d0a1a525 | ||
|
|
0a5e50a9fe | ||
|
|
3f5b7ed020 | ||
|
|
9d9802c660 | ||
|
|
27c579652a | ||
|
|
8ffa6b3c13 | ||
|
|
83f6efc33d | ||
|
|
47f1928610 | ||
|
|
7b3d961465 | ||
|
|
22b2e18d91 | ||
|
|
f6c9c0c59f | ||
|
|
d8c9d24a9c | ||
|
|
a466b73267 | ||
|
|
1ce14fb014 | ||
|
|
8bbf60fb38 | ||
|
|
f2d7c02290 | ||
|
|
65ddfc21b6 | ||
|
|
163619de60 | ||
|
|
29c4d554a0 | ||
|
|
3e59569d0b | ||
|
|
fb8483407b | ||
|
|
ec8b7f86d0 | ||
|
|
9899d59010 | ||
|
|
789e976ace | ||
|
|
d5bf2555a3 | ||
|
|
be672813f6 | ||
|
|
746a7be08c | ||
|
|
c222ee80fa | ||
|
|
4950bd038d | ||
|
|
058336a071 | ||
|
|
6823388a85 | ||
|
|
b68d097eb6 | ||
|
|
c97a22776d | ||
|
|
c484dbcca5 | ||
|
|
54f15d7afe | ||
|
|
05441188be | ||
|
|
25a2d31be7 | ||
|
|
58a4e0d545 | ||
|
|
ad06b4ce5e | ||
|
|
be3827b088 | ||
|
|
a136aaf502 | ||
|
|
40d91a8eae | ||
|
|
5b81a81ac4 | ||
|
|
328ddb2927 | ||
|
|
06b9622302 | ||
|
|
1218649202 | ||
|
|
cbea8f5a53 | ||
|
|
f42e644486 | ||
|
|
a40490b946 | ||
|
|
ad98693f3d | ||
|
|
7b4aaca975 | ||
|
|
400e59a96d | ||
|
|
09276b72a6 | ||
|
|
ec18304362 | ||
|
|
4cf411f393 | ||
|
|
2b0935adf4 | ||
|
|
cbdc5fa85f | ||
|
|
2a06c40a09 | ||
|
|
f499e3dd36 | ||
|
|
48d21fa2bf | ||
|
|
c91c69272b | ||
|
|
91f4fa744e | ||
|
|
c2abd4aaa6 | ||
|
|
617ad84f96 | ||
|
|
33b6bfa1b9 | ||
|
|
4e03afd191 | ||
|
|
3512b73bc3 | ||
|
|
d0ac45cb08 | ||
|
|
ab3d950bd3 | ||
|
|
44ddd79356 | ||
|
|
054ddf661f | ||
|
|
da466a3bdd | ||
|
|
42f0c2d78f | ||
|
|
5853784a31 | ||
|
|
5b20295620 | ||
|
|
68e151c2a3 | ||
|
|
dd764a70a2 | ||
|
|
12defe0d12 | ||
|
|
8868dd5785 | ||
|
|
e787d585a4 | ||
|
|
5eb7518ce2 | ||
|
|
5be93da111 |
No files matched your search
@@ -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.
|
||||
|
||||
Clobber for Idle GC backout
|
||||
Clobber for removal of network tickler
|
||||
@@ -18,10 +18,6 @@
|
||||
#endif
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#if (MOZ_WIDGET_GTK == 3)
|
||||
extern "C" __attribute__((weak,visibility("default"))) int atk_bridge_adaptor_init(int*, char **[]);
|
||||
#endif
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
@@ -33,12 +29,20 @@ extern "C" {
|
||||
typedef GType (* AtkGetTypeType) (void);
|
||||
typedef void (*GnomeAccessibilityInit) (void);
|
||||
typedef void (*GnomeAccessibilityShutdown) (void);
|
||||
#if (MOZ_WIDGET_GTK == 3)
|
||||
typedef int (*AtkBridgeAdaptorInit) (int*, char***);
|
||||
#endif
|
||||
}
|
||||
|
||||
static PRLibrary* sATKLib = nullptr;
|
||||
static const char sATKLibName[] = "libatk-1.0.so.0";
|
||||
static const char sATKHyperlinkImplGetTypeSymbol[] =
|
||||
"atk_hyperlink_impl_get_type";
|
||||
#if (MOZ_WIDGET_GTK == 3)
|
||||
static PRLibrary* sAtkBridgeAdaptorLib = nullptr;
|
||||
static const char sAtkBridgeAdaptorLibName[] = "libatk-bridge-2.0.so.0";
|
||||
static const char sAtkBridgeAdaptorInitSymbol[] = "atk_bridge_adaptor_init";
|
||||
#endif
|
||||
|
||||
gboolean toplevel_event_watcher(GSignalInvocationHint*, guint, const GValue*,
|
||||
gpointer);
|
||||
@@ -127,6 +131,38 @@ LoadGtkModule(GnomeAccessibilityModule& aModule)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#if (MOZ_WIDGET_GTK == 3)
|
||||
static bool
|
||||
InitAtkBridgeAdaptor()
|
||||
{
|
||||
AtkBridgeAdaptorInit initBridge =
|
||||
reinterpret_cast<AtkBridgeAdaptorInit>(
|
||||
PR_FindFunctionSymbolAndLibrary(sAtkBridgeAdaptorInitSymbol,
|
||||
&sAtkBridgeAdaptorLib));
|
||||
|
||||
if (!initBridge) {
|
||||
sAtkBridgeAdaptorLib = PR_LoadLibrary(sAtkBridgeAdaptorLibName);
|
||||
if (sAtkBridgeAdaptorLib) {
|
||||
initBridge =
|
||||
reinterpret_cast<AtkBridgeAdaptorInit>(
|
||||
PR_FindFunctionSymbol(sAtkBridgeAdaptorLib,
|
||||
sAtkBridgeAdaptorInitSymbol));
|
||||
if (!initBridge) {
|
||||
PR_UnloadLibrary(sAtkBridgeAdaptorLib);
|
||||
sAtkBridgeAdaptorLib = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!initBridge) {
|
||||
return false;
|
||||
}
|
||||
|
||||
initBridge(nullptr, nullptr);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
a11y::PlatformInit()
|
||||
{
|
||||
@@ -181,9 +217,7 @@ a11y::PlatformInit()
|
||||
// Init atk-bridge now
|
||||
PR_SetEnv("NO_AT_BRIDGE=0");
|
||||
#if (MOZ_WIDGET_GTK == 3)
|
||||
if (atk_bridge_adaptor_init) {
|
||||
atk_bridge_adaptor_init(nullptr, nullptr);
|
||||
} else
|
||||
if (!InitAtkBridgeAdaptor())
|
||||
#endif
|
||||
{
|
||||
nsresult rv = LoadGtkModule(sAtkBridge);
|
||||
@@ -228,6 +262,13 @@ a11y::PlatformShutdown()
|
||||
sAtkBridge.init = nullptr;
|
||||
sAtkBridge.shutdown = nullptr;
|
||||
}
|
||||
#if (MOZ_WIDGET_GTK == 3)
|
||||
if (sAtkBridgeAdaptorLib) {
|
||||
// Do not shutdown/unload atk-bridge; an exit function registered by
|
||||
// the bridge will take care of it.
|
||||
sAtkBridgeAdaptorLib = nullptr;
|
||||
}
|
||||
#endif
|
||||
#if (MOZ_WIDGET_GTK == 2)
|
||||
if (sGail.lib) {
|
||||
// Do not shutdown gail because
|
||||
|
||||
@@ -43,8 +43,6 @@ gyp_vars.update({
|
||||
'arm_neon': 0,
|
||||
'arm_neon_optional': 1,
|
||||
|
||||
'moz_webrtc_omx': 0,
|
||||
'moz_webrtc_mediacodec': 0,
|
||||
|
||||
# Turn off multi monitor screen share
|
||||
'multi_monitor_screenshare%' : 0,
|
||||
|
||||
@@ -344,7 +344,7 @@ def split_triplet(triplet):
|
||||
if cpu.endswith('86') or (cpu.startswith('i') and '86' in cpu):
|
||||
canonical_cpu = 'x86'
|
||||
endianness = 'little'
|
||||
elif cpu in ('x86_64', 'ia64'):
|
||||
elif cpu == 'x86_64':
|
||||
canonical_cpu = cpu
|
||||
endianness = 'little'
|
||||
elif cpu in ('s390', 's390x'):
|
||||
|
||||
@@ -164,6 +164,7 @@ def old_configure_options(*options):
|
||||
'--enable-negotiateauth',
|
||||
'--enable-nfc',
|
||||
'--enable-npapi',
|
||||
'--enable-npapi-gtk2',
|
||||
'--enable-nspr-build',
|
||||
'--enable-official-branding',
|
||||
'--enable-official-vendor',
|
||||
|
||||
@@ -290,11 +290,6 @@ fi
|
||||
if [ -n "$LD_LIBRARY_PATH_64" ]; then
|
||||
LD_LIBRARY_PATH_64=${MOZ_DIST_BIN}:${MOZ_DIST_BIN}/plugins:${MRE_HOME}${LD_LIBRARY_PATH_64:+":$LD_LIBRARY_PATH_64"}
|
||||
fi
|
||||
#
|
||||
#
|
||||
## Set SHLIB_PATH for HPUX
|
||||
SHLIB_PATH=${MOZ_DIST_BIN}:${MRE_HOME}${SHLIB_PATH:+":$SHLIB_PATH"}
|
||||
#
|
||||
## Set LIBPATH for AIX
|
||||
LIBPATH=${MOZ_DIST_BIN}:${MRE_HOME}${LIBPATH:+":$LIBPATH"}
|
||||
#
|
||||
@@ -339,7 +334,6 @@ then
|
||||
fi
|
||||
echo "DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH"
|
||||
echo " LIBRARY_PATH=$LIBRARY_PATH"
|
||||
echo " SHLIB_PATH=$SHLIB_PATH"
|
||||
echo " LIBPATH=$LIBPATH"
|
||||
echo " ADDON_PATH=$ADDON_PATH"
|
||||
echo " MOZ_PROGRAM=$MOZ_PROGRAM"
|
||||
@@ -350,7 +344,7 @@ then
|
||||
fi
|
||||
#
|
||||
export MOZILLA_FIVE_HOME LD_LIBRARY_PATH
|
||||
export SHLIB_PATH LIBPATH LIBRARY_PATH ADDON_PATH DYLD_LIBRARY_PATH
|
||||
export LIBPATH LIBRARY_PATH ADDON_PATH DYLD_LIBRARY_PATH
|
||||
|
||||
if [ $moz_debug -eq 1 ]
|
||||
then
|
||||
|
||||
@@ -448,7 +448,6 @@ gtk/gtkx.h
|
||||
gtk/gtkunixprint.h
|
||||
HIToolbox/HIToolbox.h
|
||||
hlink.h
|
||||
ia64/sys/inline.h
|
||||
Icons.h
|
||||
iconv.h
|
||||
ieeefp.h
|
||||
|
||||
@@ -143,7 +143,8 @@ TooltipsOverlay.prototype = {
|
||||
// Font preview tooltip
|
||||
if (type === VIEW_NODE_VALUE_TYPE && prop.property === "font-family") {
|
||||
let value = prop.value.toLowerCase();
|
||||
if (value !== "inherit" && value !== "unset" && value !== "initial" && value !== "revert") {
|
||||
if (value !== "inherit" && value !== "unset" && value !== "initial" &&
|
||||
value !== "revert" && value !== "revert-layer") {
|
||||
tooltipType = TOOLTIP_FONTFAMILY_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,21 +204,22 @@ function initialHTML(doc) {
|
||||
os = "linux";
|
||||
}
|
||||
|
||||
let base = doc.createElement("base");
|
||||
base.href = "resource://devtools/client/jsonview/";
|
||||
// The appRoot URI is prepended to all URIs instead of using a <base> element
|
||||
// because the latter can cause spurious network requests (UXP Issue #3122)
|
||||
let appRoot = "resource://devtools/client/jsonview/";
|
||||
|
||||
let style = doc.createElement("link");
|
||||
style.rel = "stylesheet";
|
||||
style.type = "text/css";
|
||||
style.href = base.href +"css/main.css";
|
||||
style.href = appRoot +"css/main.css";
|
||||
|
||||
let script = doc.createElement("script");
|
||||
script.src = base.href + "lib/require.js";
|
||||
script.dataset.main = "viewer-config";
|
||||
script.src = appRoot + "lib/require.js";
|
||||
script.dataset.main = appRoot + "viewer-config.js";
|
||||
script.defer = true;
|
||||
|
||||
let head = doc.createElement("head");
|
||||
head.append(base, style, script);
|
||||
head.append(style, script);
|
||||
|
||||
return "<!DOCTYPE html>\n" +
|
||||
startTag("html", {
|
||||
|
||||
@@ -4,6 +4,8 @@ subsuite = devtools
|
||||
support-files =
|
||||
array_json.json
|
||||
array_json.json^headers^
|
||||
csp_json.json
|
||||
csp_json.json^headers^
|
||||
doc_frame_script.js
|
||||
head.js
|
||||
invalid_json.json
|
||||
@@ -22,6 +24,7 @@ subsuite = clipboard
|
||||
subsuite = clipboard
|
||||
[browser_jsonview_copy_rawdata.js]
|
||||
subsuite = clipboard
|
||||
[browser_jsonview_csp_json.js]
|
||||
[browser_jsonview_filter.js]
|
||||
[browser_jsonview_invalid_json.js]
|
||||
[browser_jsonview_valid_json.js]
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_JSON_URL = URL_ROOT + "csp_json.json";
|
||||
|
||||
add_task(function* () {
|
||||
info("Test CSP JSON started");
|
||||
|
||||
yield addJsonViewTab(TEST_JSON_URL);
|
||||
|
||||
let count = yield getElementCount(".jsonPanelBox .treeTable .treeRow");
|
||||
is(count, 1, "There must be one row");
|
||||
});
|
||||
@@ -0,0 +1 @@
|
||||
{"csp": true}
|
||||
@@ -0,0 +1,2 @@
|
||||
Content-Type: application/json
|
||||
Content-Security-Policy: default-src 'none'; base-uri 'none';
|
||||
@@ -23,7 +23,7 @@
|
||||
* of the code base, so it's consistent and modules can be easily reused.
|
||||
*/
|
||||
require.config({
|
||||
baseUrl: ".",
|
||||
baseUrl: "resource://devtools/client/jsonview/",
|
||||
paths: {
|
||||
"devtools/client/shared": "resource://devtools/client/shared",
|
||||
"devtools/shared": "resource://devtools/shared",
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
# 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/.
|
||||
|
||||
JS_PREFERENCE_PP_FILES += [
|
||||
JS_PREFERENCE_FILES += [
|
||||
'devtools.js',
|
||||
]
|
||||
@@ -10,7 +10,8 @@ const SPECIALVALUES = new Set([
|
||||
"initial",
|
||||
"inherit",
|
||||
"unset",
|
||||
"revert"
|
||||
"revert",
|
||||
"revert-layer"
|
||||
]);
|
||||
|
||||
const {getCSSLexer} = require("devtools/shared/css/lexer");
|
||||
|
||||
@@ -99,7 +99,14 @@ const filterList = [
|
||||
];
|
||||
|
||||
// Valid values that shouldn't be parsed for filters.
|
||||
const SPECIAL_VALUES = new Set(["none", "unset", "initial", "inherit", "revert"]);
|
||||
const SPECIAL_VALUES = new Set([
|
||||
"none",
|
||||
"unset",
|
||||
"initial",
|
||||
"inherit",
|
||||
"revert",
|
||||
"revert-layer"
|
||||
]);
|
||||
|
||||
/**
|
||||
* A CSS Filter editor widget used to add/remove/modify
|
||||
|
||||
@@ -20,7 +20,8 @@ const SPECIALVALUES = new Set([
|
||||
"inherit",
|
||||
"transparent",
|
||||
"unset",
|
||||
"revert"
|
||||
"revert",
|
||||
"revert-layer"
|
||||
]);
|
||||
|
||||
/**
|
||||
|
||||
@@ -43,7 +43,7 @@ class MachCommands(MachCommandBase):
|
||||
if not os.path.exists(generated_dir):
|
||||
generated_dir = mozpath.join(self.topsrcdir, 'platform',
|
||||
'devtools/shared/css/generated')
|
||||
else:
|
||||
if not os.path.exists(generated_dir):
|
||||
raise Exception('Directory expected at %s does not exist.' % generated_dir)
|
||||
self.generated_dir = generated_dir
|
||||
|
||||
@@ -75,6 +75,9 @@ class MachCommands(MachCommandBase):
|
||||
contents = subprocess.check_output([xpcshell_path, '-g', gre_path,
|
||||
'-a', browser_path, script_path],
|
||||
env = sub_env)
|
||||
if not isinstance(contents, str):
|
||||
contents = contents.decode('utf-8')
|
||||
|
||||
# Extract just the output between the delimiters as the xpcshell output can
|
||||
# have extra output that we don't want.
|
||||
contents = contents.split('DEVTOOLS_CSS_DB_DELIMITER')[1]
|
||||
@@ -88,13 +91,13 @@ class MachCommands(MachCommandBase):
|
||||
destination_path = mozpath.join(self.generated_dir,
|
||||
'properties-db.js')
|
||||
|
||||
with open(js_template_path, 'rb') as handle:
|
||||
with open(js_template_path, 'r') as handle:
|
||||
js_template = handle.read()
|
||||
|
||||
preamble = '/* THIS IS AN AUTOGENERATED FILE. DO NOT EDIT */\n\n'
|
||||
contents = string.Template(js_template).substitute(substitutions)
|
||||
|
||||
with open(destination_path, 'wb') as destination:
|
||||
with open(destination_path, 'w') as destination:
|
||||
destination.write(preamble + contents)
|
||||
|
||||
print(('The database was successfully generated at ' + destination_path))
|
||||
File diff suppressed because it is too large.
Load diff
@@ -274,7 +274,7 @@ public:
|
||||
}
|
||||
|
||||
template<typename T,
|
||||
typename = typename std::enable_if<std::is_enum<T>::value>::type>
|
||||
typename = typename std::enable_if_t<std::is_enum_v<T>>>
|
||||
EnumTable(const char* aTag, T aValue)
|
||||
: tag(aTag)
|
||||
, value(static_cast<int16_t>(aValue))
|
||||
|
||||
@@ -1487,8 +1487,15 @@ nsGenericHTMLElement::MapImageSizeAttributesInto(const nsMappedAttributes* aAttr
|
||||
}
|
||||
|
||||
if (w && h && *w != 0 && *h != 0) {
|
||||
nsCSSValue* aspect_ratio = aData->ValueForAspectRatio();
|
||||
aspect_ratio->SetFloatValue((float(*w) / float(*h)), eCSSUnit_Number);
|
||||
nsCSSValue width;
|
||||
width.SetFloatValue(float(*w), eCSSUnit_Number);
|
||||
nsCSSValue height;
|
||||
height.SetFloatValue(float(*h), eCSSUnit_Number);
|
||||
nsCSSValue ratio;
|
||||
ratio.SetPairValue(width, height);
|
||||
nsCSSValue autoValue;
|
||||
autoValue.SetAutoValue();
|
||||
aData->ValueForAspectRatio()->SetPairValue(autoValue, ratio);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2455,7 +2455,7 @@ ContentChild::RecvUpdateWindow(const uintptr_t& aChildId)
|
||||
if (parentInstance) {
|
||||
// sync! update call to the plugin instance that forces the
|
||||
// plugin to paint its child window.
|
||||
parentInstance->CallUpdateWindow();
|
||||
Unused << parentInstance->CallUpdateWindow();
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
|
||||
@@ -29,8 +29,7 @@ enum {
|
||||
* Abstract interface for managing audio and video devices. Each platform
|
||||
* must implement a concrete class that will map these classes and methods
|
||||
* to the appropriate backend. For example, on Desktop platforms, these will
|
||||
* correspond to equivalent webrtc (GIPS) calls, and on B2G they will map to
|
||||
* a Gonk interface.
|
||||
* correspond to equivalent webrtc (GIPS) calls.
|
||||
*/
|
||||
class MediaEngineVideoSource;
|
||||
class MediaEngineAudioSource;
|
||||
@@ -302,7 +301,6 @@ public:
|
||||
|
||||
/* If implementation of MediaEngineSource supports TakePhoto(), the picture
|
||||
* should be return via aCallback object. Otherwise, it returns NS_ERROR_NOT_IMPLEMENTED.
|
||||
* Currently, only Gonk MediaEngineSource implementation supports it.
|
||||
*/
|
||||
virtual nsresult TakePhoto(MediaEnginePhotoCallback* aCallback) = 0;
|
||||
|
||||
|
||||
@@ -36,8 +36,8 @@ bool MediaEngineCameraVideoSource::AppendToTrack(SourceMediaStream* aSource,
|
||||
return aSource->AppendToTrack(aID, &(segment));
|
||||
}
|
||||
|
||||
// Sub-classes (B2G or desktop) should overload one of both of these two methods
|
||||
// to provide capabilities
|
||||
// Subclasses should overload one or both of these methods to provide
|
||||
// capabilities.
|
||||
size_t
|
||||
MediaEngineCameraVideoSource::NumCapabilities() const
|
||||
{
|
||||
@@ -324,21 +324,6 @@ MediaEngineCameraVideoSource::SetName(nsString aName)
|
||||
bool hasFacingMode = false;
|
||||
VideoFacingModeEnum facingMode = VideoFacingModeEnum::User;
|
||||
|
||||
// Set facing mode based on device name.
|
||||
#if defined(ANDROID)
|
||||
// Names are generated. Example: "Camera 0, Facing back, Orientation 90"
|
||||
//
|
||||
// See media/webrtc/trunk/webrtc/modules/video_capture/android/java/src/org/
|
||||
// webrtc/videoengine/VideoCaptureDeviceInfoAndroid.java
|
||||
|
||||
if (aName.Find(NS_LITERAL_STRING("Facing back")) != kNotFound) {
|
||||
hasFacingMode = true;
|
||||
facingMode = VideoFacingModeEnum::Environment;
|
||||
} else if (aName.Find(NS_LITERAL_STRING("Facing front")) != kNotFound) {
|
||||
hasFacingMode = true;
|
||||
facingMode = VideoFacingModeEnum::User;
|
||||
}
|
||||
#endif // ANDROID
|
||||
#ifdef XP_MACOSX
|
||||
// Kludge to test user-facing cameras on OSX.
|
||||
if (aName.Find(NS_LITERAL_STRING("Face")) != -1) {
|
||||
|
||||
@@ -108,7 +108,7 @@ protected:
|
||||
nsTArray<PrincipalHandle> mPrincipalHandles; // Directly mapped to mSources.
|
||||
RefPtr<layers::Image> mImage;
|
||||
RefPtr<layers::ImageContainer> mImageContainer;
|
||||
int mWidth, mHeight; // protected with mMonitor on Gonk due to different threading
|
||||
int mWidth, mHeight; // protected with mMonitor
|
||||
// end of data protected by mMonitor
|
||||
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#ifdef FF
|
||||
#undef FF
|
||||
#endif
|
||||
#include "webrtc/modules/audio_device/opensl/single_rw_fifo.h"
|
||||
#include "SingleRwFifo.h"
|
||||
|
||||
#define CHANNELS 1
|
||||
#define ENCODING "L16"
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "SingleRwFifo.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
static int
|
||||
UpdatePos(int pos, int capacity)
|
||||
{
|
||||
return (pos + 1) % capacity;
|
||||
}
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
namespace subtle {
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
inline void
|
||||
MemoryBarrier()
|
||||
{
|
||||
::MemoryBarrier();
|
||||
}
|
||||
#elif defined(__GNUC__) || defined(__clang__)
|
||||
inline void
|
||||
MemoryBarrier()
|
||||
{
|
||||
__sync_synchronize();
|
||||
}
|
||||
#else
|
||||
#error Add an implementation of MemoryBarrier() for this platform!
|
||||
#endif
|
||||
|
||||
} // namespace subtle
|
||||
|
||||
SingleRwFifo::SingleRwFifo(int capacity)
|
||||
: capacity_(capacity)
|
||||
, size_(0)
|
||||
, read_pos_(0)
|
||||
, write_pos_(0)
|
||||
{
|
||||
queue_.reset(new int8_t*[capacity_]);
|
||||
}
|
||||
|
||||
SingleRwFifo::~SingleRwFifo()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
SingleRwFifo::Push(int8_t* mem)
|
||||
{
|
||||
assert(mem);
|
||||
|
||||
// Ensure that there is space for the new data in the FIFO. There is only one
|
||||
// writer, so the other thread is guaranteed only to decrease the size.
|
||||
const int free_slots = capacity() - size();
|
||||
if (free_slots <= 0) {
|
||||
// Size can be queried outside of Push. The caller is expected to ensure
|
||||
// that Push will be successful before calling it.
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
queue_[write_pos_] = mem;
|
||||
// Ensure that |size_| is updated after the stored pointer is visible.
|
||||
subtle::MemoryBarrier();
|
||||
++size_;
|
||||
write_pos_ = UpdatePos(write_pos_, capacity());
|
||||
}
|
||||
|
||||
int8_t*
|
||||
SingleRwFifo::Pop()
|
||||
{
|
||||
int8_t* ret_val = nullptr;
|
||||
if (size() <= 0) {
|
||||
// Size can be queried outside of Pop. The caller is expected to ensure
|
||||
// that Pop will be successful before calling it.
|
||||
assert(false);
|
||||
return ret_val;
|
||||
}
|
||||
ret_val = queue_[read_pos_];
|
||||
// Ensure that |size_| is updated after the stored pointer is read.
|
||||
subtle::MemoryBarrier();
|
||||
--size_;
|
||||
read_pos_ = UpdatePos(read_pos_, capacity());
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
+5
-8
@@ -8,8 +8,8 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_SINGLE_RW_FIFO_H_
|
||||
#define WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_SINGLE_RW_FIFO_H_
|
||||
#ifndef DOM_MEDIA_WEBRTC_SINGLE_RW_FIFO_H_
|
||||
#define DOM_MEDIA_WEBRTC_SINGLE_RW_FIFO_H_
|
||||
|
||||
#include "webrtc/base/scoped_ptr.h"
|
||||
#include "webrtc/system_wrappers/interface/atomic32.h"
|
||||
@@ -17,10 +17,9 @@
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Implements a lock-free FIFO losely based on
|
||||
// Implements a lock-free FIFO loosely based on
|
||||
// http://src.chromium.org/viewvc/chrome/trunk/src/media/base/audio_fifo.cc
|
||||
// Note that this class assumes there is one producer (writer) and one
|
||||
// consumer (reader) thread.
|
||||
// This class assumes there is one producer and one consumer thread.
|
||||
class SingleRwFifo {
|
||||
public:
|
||||
explicit SingleRwFifo(int capacity);
|
||||
@@ -29,8 +28,6 @@ class SingleRwFifo {
|
||||
void Push(int8_t* mem);
|
||||
int8_t* Pop();
|
||||
|
||||
void Clear();
|
||||
|
||||
int size() { return size_.Value(); }
|
||||
int capacity() const { return capacity_; }
|
||||
|
||||
@@ -46,4 +43,4 @@ class SingleRwFifo {
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_SINGLE_RW_FIFO_H_
|
||||
#endif // DOM_MEDIA_WEBRTC_SINGLE_RW_FIFO_H_
|
||||
@@ -38,6 +38,7 @@ if CONFIG['MOZ_WEBRTC']:
|
||||
# MediaEngineWebRTC.cpp needs to be built separately.
|
||||
SOURCES += [
|
||||
'MediaEngineWebRTC.cpp',
|
||||
'SingleRwFifo.cpp',
|
||||
]
|
||||
LOCAL_INCLUDES += [
|
||||
'/dom/base',
|
||||
@@ -68,8 +69,7 @@ include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
# Suppress some GCC/clang warnings being treated as errors:
|
||||
# - about attributes on forward declarations for types that are already
|
||||
# defined, which complains about important MOZ_EXPORT attributes for
|
||||
# android API types
|
||||
# defined, which complains about important MOZ_EXPORT attributes.
|
||||
if CONFIG['GNU_CC'] or CONFIG['CLANG_CL']:
|
||||
CXXFLAGS += [
|
||||
'-Wno-error=attributes',
|
||||
|
||||
@@ -194,7 +194,7 @@ static void FreeStringArray(uint32_t variants, char ** array)
|
||||
|
||||
static bool CanLoadPlugin(char16ptr_t aBinaryPath)
|
||||
{
|
||||
#if defined(_M_IX86) || defined(_M_X64) || defined(_M_IA64)
|
||||
#if defined(_M_IX86) || defined(_M_X64)
|
||||
bool canLoad = false;
|
||||
|
||||
HANDLE file = CreateFileW(aBinaryPath, GENERIC_READ,
|
||||
@@ -214,8 +214,6 @@ static bool CanLoadPlugin(char16ptr_t aBinaryPath)
|
||||
canLoad = (arch == IMAGE_FILE_MACHINE_I386);
|
||||
#elif defined(_M_X64)
|
||||
canLoad = (arch == IMAGE_FILE_MACHINE_AMD64);
|
||||
#elif defined(_M_IA64)
|
||||
canLoad = (arch == IMAGE_FILE_MACHINE_IA64);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,12 @@ using namespace std;
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
#include <gdk/gdk.h>
|
||||
#if (GTK_MAJOR_VERSION == 3)
|
||||
#include <gtk/gtkx.h>
|
||||
#endif
|
||||
#ifdef MOZ_ENABLE_NPAPI_GTK2
|
||||
#include "gtk2xtbin.h"
|
||||
#endif
|
||||
|
||||
#elif defined(OS_WIN)
|
||||
|
||||
@@ -208,7 +213,9 @@ PluginInstanceChild::PluginInstanceChild(const NPPluginFuncs* aPluginIface,
|
||||
memset(&mWsInfo, 0, sizeof(mWsInfo));
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
mWsInfo.display = nullptr;
|
||||
#ifdef MOZ_ENABLE_NPAPI_GTK2
|
||||
mXtClient.top_widget = nullptr;
|
||||
#endif
|
||||
#else
|
||||
mWsInfo.display = DefaultXDisplay();
|
||||
#endif
|
||||
@@ -620,15 +627,17 @@ PluginInstanceChild::NPN_SetValue(NPPVariable aVar, void* aValue)
|
||||
NPWindowType newWindowType = windowed ? NPWindowTypeWindow : NPWindowTypeDrawable;
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
if (mWindow.type != newWindowType && mWsInfo.display) {
|
||||
// plugin type has been changed but we already have a valid display
|
||||
// so update it for the recent plugin mode
|
||||
if (mXEmbed || !windowed) {
|
||||
// Use default GTK display for XEmbed and windowless plugins
|
||||
mWsInfo.display = DefaultXDisplay();
|
||||
}
|
||||
else {
|
||||
mWsInfo.display = xt_client_get_display();
|
||||
}
|
||||
// plugin type has been changed but we already have a valid display
|
||||
// so update it for the recent plugin mode
|
||||
#ifdef MOZ_ENABLE_NPAPI_GTK2
|
||||
if (!mXEmbed && windowed) {
|
||||
mWsInfo.display = xt_client_get_display();
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
// Use default GTK display for XEmbed and windowless plugins.
|
||||
mWsInfo.display = DefaultXDisplay();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
mWindow.type = newWindowType;
|
||||
@@ -1214,12 +1223,18 @@ bool PluginInstanceChild::CreateWindow(const NPRemoteWindow& aWindow)
|
||||
if (mXEmbed) {
|
||||
mWindow.window = reinterpret_cast<void*>(aWindow.window);
|
||||
}
|
||||
#ifdef MOZ_ENABLE_NPAPI_GTK2
|
||||
else {
|
||||
Window browserSocket = (Window)(aWindow.window);
|
||||
xt_client_init(&mXtClient, mWsInfo.visual, mWsInfo.colormap, mWsInfo.depth);
|
||||
xt_client_create(&mXtClient, browserSocket, mWindow.width, mWindow.height);
|
||||
mWindow.window = (void *)XtWindow(mXtClient.child_widget);
|
||||
}
|
||||
}
|
||||
#else
|
||||
else {
|
||||
mWindow.window = reinterpret_cast<void*>(aWindow.window);
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
mWindow.window = reinterpret_cast<void*>(aWindow.window);
|
||||
#endif
|
||||
@@ -1239,7 +1254,7 @@ void PluginInstanceChild::DeleteWindow()
|
||||
if (!mWindow.window)
|
||||
return;
|
||||
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
#ifdef MOZ_ENABLE_NPAPI_GTK2
|
||||
if (mXtClient.top_widget) {
|
||||
xt_client_unrealize(&mXtClient);
|
||||
xt_client_destroy(&mXtClient);
|
||||
@@ -1321,7 +1336,7 @@ PluginInstanceChild::AnswerNPP_SetWindow(const NPRemoteWindow& aWindow)
|
||||
CreateWindow(aWindow);
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
#ifdef MOZ_ENABLE_NPAPI_GTK2
|
||||
if (mXEmbed && gtk_check_version(2,18,7) != nullptr) { // older
|
||||
if (aWindow.type == NPWindowTypeWindow) {
|
||||
GdkWindow* socket_window = gdk_window_lookup(static_cast<GdkNativeWindow>(aWindow.window));
|
||||
@@ -1456,19 +1471,27 @@ PluginInstanceChild::Initialize()
|
||||
if (mWindow.type == NPWindowTypeWindow) {
|
||||
AnswerNPP_GetValue_NPPVpluginNeedsXEmbed(&mXEmbed, &rv);
|
||||
|
||||
#ifdef MOZ_ENABLE_NPAPI_GTK2
|
||||
// Set up Xt loop for windowed plugins without XEmbed support
|
||||
if (!mXEmbed) {
|
||||
xt_client_xloop_create();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Use default GTK display for XEmbed and windowless plugins
|
||||
// Use default GTK display for XEmbed and windowless plugins.
|
||||
if (mXEmbed || mWindow.type != NPWindowTypeWindow) {
|
||||
mWsInfo.display = DefaultXDisplay();
|
||||
}
|
||||
#ifdef MOZ_ENABLE_NPAPI_GTK2
|
||||
else {
|
||||
mWsInfo.display = xt_client_get_display();
|
||||
}
|
||||
#else
|
||||
else {
|
||||
mWsInfo.display = DefaultXDisplay();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return true;
|
||||
@@ -4656,7 +4679,7 @@ PluginInstanceChild::Destroy()
|
||||
|
||||
mPendingAsyncCalls.Clear();
|
||||
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
#if defined(MOZ_WIDGET_GTK) && defined(MOZ_ENABLE_NPAPI_GTK2)
|
||||
if (mWindow.type == NPWindowTypeWindow && !mXEmbed) {
|
||||
xt_client_xloop_destroy();
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
#include <map>
|
||||
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
#if defined(MOZ_WIDGET_GTK) && defined(MOZ_ENABLE_NPAPI_GTK2)
|
||||
#include "gtk2xtbin.h"
|
||||
#endif
|
||||
|
||||
@@ -462,6 +462,8 @@ private:
|
||||
NPSetWindowCallbackStruct mWsInfo;
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
bool mXEmbed;
|
||||
#endif
|
||||
#ifdef MOZ_ENABLE_NPAPI_GTK2
|
||||
XtClient mXtClient;
|
||||
#endif
|
||||
#elif defined(OS_WIN)
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
#include <gtk/gtk.h>
|
||||
#if (GTK_MAJOR_VERSION == 3)
|
||||
#include <gtk/gtkx.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "nsIFile.h"
|
||||
@@ -1101,7 +1104,11 @@ _getvalue(NPP aNPP,
|
||||
return InstCast(aNPP)->NPN_GetValue(aVariable, aValue);
|
||||
}
|
||||
else {
|
||||
#ifdef MOZ_ENABLE_NPAPI_GTK2
|
||||
*(void **)aValue = xt_client_get_display();
|
||||
#else
|
||||
*(void **)aValue = DefaultXDisplay();
|
||||
#endif
|
||||
}
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
@@ -143,11 +143,13 @@ LOCAL_INCLUDES += [
|
||||
|
||||
DEFINES['FORCE_PR_LOG'] = True
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'gtk3':
|
||||
CXXFLAGS += CONFIG['TK_CFLAGS']
|
||||
else:
|
||||
if (CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gtk3' and
|
||||
CONFIG['MOZ_ENABLE_NPAPI'] and
|
||||
CONFIG['MOZ_ENABLE_NPAPI_GTK2']):
|
||||
# Force build against gtk+2 for struct offsets and such.
|
||||
CXXFLAGS += CONFIG['MOZ_GTK2_CFLAGS']
|
||||
else:
|
||||
CXXFLAGS += CONFIG['TK_CFLAGS']
|
||||
|
||||
CXXFLAGS += CONFIG['MOZ_CAIRO_CFLAGS']
|
||||
|
||||
|
||||
@@ -25,6 +25,8 @@ interface CSSStyleSheet : StyleSheet {
|
||||
unsigned long insertRule(DOMString rule, optional unsigned long index = 0);
|
||||
[Throws, NeedsSubjectPrincipal]
|
||||
void deleteRule(unsigned long index);
|
||||
[Throws]
|
||||
void replaceSync(DOMString text);
|
||||
|
||||
// Non-standard WebKit things, see https://github.com/w3c/csswg-drafts/pull/3900.
|
||||
[Throws, NeedsSubjectPrincipal, BinaryName="cssRules"]
|
||||
|
||||
@@ -301,6 +301,7 @@ LoadContextOptions(const char* aPrefName, void* /* aClosure */)
|
||||
.setAsyncStack(GetWorkerPref<bool>(NS_LITERAL_CSTRING("asyncstack")))
|
||||
.setWerror(GetWorkerPref<bool>(NS_LITERAL_CSTRING("werror")))
|
||||
.setStreams(GetWorkerPref<bool>(NS_LITERAL_CSTRING("streams")))
|
||||
.setWeakRefs(GetWorkerPref<bool>(NS_LITERAL_CSTRING("weakrefs")))
|
||||
.setExtraWarnings(GetWorkerPref<bool>(NS_LITERAL_CSTRING("strict")))
|
||||
.setArrayProtoValues(GetWorkerPref<bool>(
|
||||
NS_LITERAL_CSTRING("array_prototype_values")));
|
||||
|
||||
@@ -35,6 +35,7 @@ WORKER_SIMPLE_PREF("dom.serviceWorkers.openWindow.enabled", OpenWindowEnabled, O
|
||||
WORKER_SIMPLE_PREF("dom.storageManager.enabled", StorageManagerEnabled, STORAGEMANAGER_ENABLED)
|
||||
WORKER_SIMPLE_PREF("dom.push.enabled", PushEnabled, PUSH_ENABLED)
|
||||
WORKER_SIMPLE_PREF("dom.streams.enabled", StreamsEnabled, STREAMS_ENABLED)
|
||||
WORKER_SIMPLE_PREF("javascript.options.weakrefs", WeakRefsEnabled, WEAKREFS_ENABLED)
|
||||
WORKER_SIMPLE_PREF("dom.requestcontext.enabled", RequestContextEnabled, REQUESTCONTEXT_ENABLED)
|
||||
WORKER_SIMPLE_PREF("gfx.offscreencanvas.enabled", OffscreenCanvasEnabled, OFFSCREENCANVAS_ENABLED)
|
||||
WORKER_SIMPLE_PREF("dom.webkitBlink.dirPicker.enabled", WebkitBlinkDirectoryPickerEnabled, DOM_WEBKITBLINK_DIRPICKER_WEBKITBLINK)
|
||||
|
||||
@@ -1117,6 +1117,7 @@ DrawTargetSkia::BorrowCGContext(const DrawOptions &aOptions)
|
||||
kCGImageAlphaOnly :
|
||||
kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host;
|
||||
|
||||
#if defined(MAC_OS_X_VERSION_10_6) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
|
||||
mCG = CGBitmapContextCreateWithData(mCanvasData,
|
||||
mCGSize.width,
|
||||
mCGSize.height,
|
||||
@@ -1126,6 +1127,15 @@ DrawTargetSkia::BorrowCGContext(const DrawOptions &aOptions)
|
||||
bitmapInfo,
|
||||
NULL, /* Callback when released */
|
||||
NULL);
|
||||
#else
|
||||
mCG = CGBitmapContextCreate(mCanvasData,
|
||||
mCGSize.width,
|
||||
mCGSize.height,
|
||||
8, /* bits per component */
|
||||
stride,
|
||||
mColorSpace,
|
||||
bitmapInfo);
|
||||
#endif
|
||||
if (!mCG) {
|
||||
ReleaseBits(mCanvasData);
|
||||
NS_WARNING("Could not create bitmap around skia data\n");
|
||||
|
||||
@@ -115,7 +115,7 @@ ScaledFontMac::GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget *aT
|
||||
return ScaledFontBase::GetPathForGlyphs(aBuffer, aTarget);
|
||||
}
|
||||
|
||||
#if !defined(MAC_OS_X_VERSION_10_7) || (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7)
|
||||
#ifndef USE_SKIA
|
||||
void
|
||||
ScaledFontMac::CopyGlyphsToBuilder(const GlyphBuffer &aBuffer, PathBuilder *aBuilder, const Matrix *aTransformHint)
|
||||
{
|
||||
|
||||
@@ -32,7 +32,7 @@ public:
|
||||
virtual SkTypeface* GetSkTypeface();
|
||||
#endif
|
||||
virtual already_AddRefed<Path> GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget *aTarget);
|
||||
#if !defined(MAC_OS_X_VERSION_10_7) || (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7)
|
||||
#ifndef USE_SKIA
|
||||
virtual void CopyGlyphsToBuilder(const GlyphBuffer &aBuffer, PathBuilder *aBuilder, const Matrix *aTransformHint);
|
||||
#endif
|
||||
virtual bool GetFontFileData(FontFileDataOutput aDataCallback, void *aBaton);
|
||||
|
||||
@@ -24,15 +24,21 @@
|
||||
* Skia's 32bit backend only supports 1 sizzle order at a time (compile-time).
|
||||
* This is specified by 4 defines SK_A32_SHIFT, SK_R32_SHIFT, ... for G and B.
|
||||
*
|
||||
* For easier compatibility with Skia's GPU backend, we further restrict these
|
||||
* to either (in memory-byte-order) RGBA or BGRA. Note that this "order" does
|
||||
* not directly correspond to the same shift-order, since we have to take endianess
|
||||
* into account.
|
||||
* For easier compatibility with Skia's GPU backend, Skia normally restricts
|
||||
* these to either (in memory-byte-order) RGBA or BGRA. Mozilla's big-endian
|
||||
* PowerPC port uses CoreGraphics' native ARGB pixels, so we also accept ARGB.
|
||||
* Note that this "order" does not directly correspond to the same shift-order,
|
||||
* since we have to take endianess into account.
|
||||
*
|
||||
* Here we enforce this constraint.
|
||||
*/
|
||||
|
||||
#ifdef SK_CPU_BENDIAN
|
||||
#define SK_ARGB_A32_SHIFT 24
|
||||
#define SK_ARGB_R32_SHIFT 16
|
||||
#define SK_ARGB_G32_SHIFT 8
|
||||
#define SK_ARGB_B32_SHIFT 0
|
||||
|
||||
#define SK_RGBA_R32_SHIFT 24
|
||||
#define SK_RGBA_G32_SHIFT 16
|
||||
#define SK_RGBA_B32_SHIFT 8
|
||||
@@ -43,6 +49,11 @@
|
||||
#define SK_BGRA_R32_SHIFT 8
|
||||
#define SK_BGRA_A32_SHIFT 0
|
||||
#else
|
||||
#define SK_ARGB_A32_SHIFT 0
|
||||
#define SK_ARGB_R32_SHIFT 8
|
||||
#define SK_ARGB_G32_SHIFT 16
|
||||
#define SK_ARGB_B32_SHIFT 24
|
||||
|
||||
#define SK_RGBA_R32_SHIFT 0
|
||||
#define SK_RGBA_G32_SHIFT 8
|
||||
#define SK_RGBA_B32_SHIFT 16
|
||||
@@ -54,10 +65,18 @@
|
||||
#define SK_BGRA_A32_SHIFT 24
|
||||
#endif
|
||||
|
||||
#if defined(SK_PMCOLOR_IS_RGBA) && defined(SK_PMCOLOR_IS_BGRA)
|
||||
#error "can't define PMCOLOR to be RGBA and BGRA"
|
||||
#if (defined(SK_PMCOLOR_IS_RGBA) && defined(SK_PMCOLOR_IS_BGRA)) || \
|
||||
(defined(SK_PMCOLOR_IS_RGBA) && defined(SK_PMCOLOR_IS_ARGB)) || \
|
||||
(defined(SK_PMCOLOR_IS_BGRA) && defined(SK_PMCOLOR_IS_ARGB))
|
||||
#error "can't define PMCOLOR to more than one byte order"
|
||||
#endif
|
||||
|
||||
#define LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_ARGB \
|
||||
(SK_A32_SHIFT == SK_ARGB_A32_SHIFT && \
|
||||
SK_R32_SHIFT == SK_ARGB_R32_SHIFT && \
|
||||
SK_G32_SHIFT == SK_ARGB_G32_SHIFT && \
|
||||
SK_B32_SHIFT == SK_ARGB_B32_SHIFT)
|
||||
|
||||
#define LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_RGBA \
|
||||
(SK_A32_SHIFT == SK_RGBA_A32_SHIFT && \
|
||||
SK_R32_SHIFT == SK_RGBA_R32_SHIFT && \
|
||||
@@ -76,6 +95,10 @@
|
||||
#define SK_G_INDEX (SK_G32_SHIFT/8)
|
||||
#define SK_B_INDEX (SK_B32_SHIFT/8)
|
||||
|
||||
#if defined(SK_PMCOLOR_IS_ARGB) && !LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_ARGB
|
||||
#error "SK_PMCOLOR_IS_ARGB does not match SK_*32_SHIFT values"
|
||||
#endif
|
||||
|
||||
#if defined(SK_PMCOLOR_IS_RGBA) && !LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_RGBA
|
||||
#error "SK_PMCOLOR_IS_RGBA does not match SK_*32_SHIFT values"
|
||||
#endif
|
||||
@@ -84,19 +107,22 @@
|
||||
#error "SK_PMCOLOR_IS_BGRA does not match SK_*32_SHIFT values"
|
||||
#endif
|
||||
|
||||
#if !defined(SK_PMCOLOR_IS_RGBA) && !defined(SK_PMCOLOR_IS_BGRA)
|
||||
#if !defined(SK_PMCOLOR_IS_ARGB) && !defined(SK_PMCOLOR_IS_RGBA) && !defined(SK_PMCOLOR_IS_BGRA)
|
||||
// deduce which to define from the _SHIFT defines
|
||||
|
||||
#if LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_RGBA
|
||||
#if LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_ARGB
|
||||
#define SK_PMCOLOR_IS_ARGB
|
||||
#elif LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_RGBA
|
||||
#define SK_PMCOLOR_IS_RGBA
|
||||
#elif LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_BGRA
|
||||
#define SK_PMCOLOR_IS_BGRA
|
||||
#else
|
||||
#error "need 32bit packing to be either RGBA or BGRA"
|
||||
#error "need 32bit packing to be either ARGB, RGBA, or BGRA"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// hide these now that we're done
|
||||
#undef LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_ARGB
|
||||
#undef LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_RGBA
|
||||
#undef LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_BGRA
|
||||
|
||||
@@ -131,19 +157,38 @@ static inline uint32_t SkPackARGB_as_BGRA(U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
|
||||
(g << SK_BGRA_G32_SHIFT) | (b << SK_BGRA_B32_SHIFT);
|
||||
}
|
||||
|
||||
static inline SkPMColor SkPackARGB_as_PMColor(U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
|
||||
SkASSERT_IS_BYTE(a);
|
||||
SkASSERT_IS_BYTE(r);
|
||||
SkASSERT_IS_BYTE(g);
|
||||
SkASSERT_IS_BYTE(b);
|
||||
return (a << SK_A32_SHIFT) | (r << SK_R32_SHIFT) |
|
||||
(g << SK_G32_SHIFT) | (b << SK_B32_SHIFT);
|
||||
}
|
||||
|
||||
static inline SkPMColor SkSwizzle_RGBA_to_PMColor(uint32_t c) {
|
||||
#ifdef SK_PMCOLOR_IS_RGBA
|
||||
return c;
|
||||
#else
|
||||
#elif defined(SK_PMCOLOR_IS_BGRA)
|
||||
return SkSwizzle_RB(c);
|
||||
#else
|
||||
return SkPackARGB_as_PMColor((c >> SK_RGBA_A32_SHIFT) & 0xFF,
|
||||
(c >> SK_RGBA_R32_SHIFT) & 0xFF,
|
||||
(c >> SK_RGBA_G32_SHIFT) & 0xFF,
|
||||
(c >> SK_RGBA_B32_SHIFT) & 0xFF);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline SkPMColor SkSwizzle_BGRA_to_PMColor(uint32_t c) {
|
||||
#ifdef SK_PMCOLOR_IS_BGRA
|
||||
return c;
|
||||
#else
|
||||
#elif defined(SK_PMCOLOR_IS_RGBA)
|
||||
return SkSwizzle_RB(c);
|
||||
#else
|
||||
return SkPackARGB_as_PMColor((c >> SK_BGRA_A32_SHIFT) & 0xFF,
|
||||
(c >> SK_BGRA_R32_SHIFT) & 0xFF,
|
||||
(c >> SK_BGRA_G32_SHIFT) & 0xFF,
|
||||
(c >> SK_BGRA_B32_SHIFT) & 0xFF);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -412,8 +457,7 @@ static inline SkPMColor SkPackARGB32(U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
|
||||
SkASSERT(g <= a);
|
||||
SkASSERT(b <= a);
|
||||
|
||||
return (a << SK_A32_SHIFT) | (r << SK_R32_SHIFT) |
|
||||
(g << SK_G32_SHIFT) | (b << SK_B32_SHIFT);
|
||||
return SkPackARGB_as_PMColor(a, r, g, b);
|
||||
}
|
||||
|
||||
static inline uint32_t SkPackPMColor_as_RGBA(SkPMColor c) {
|
||||
@@ -547,8 +591,7 @@ static inline SkPMColor SkFastFourByteInterp(SkPMColor src,
|
||||
* values are premultiplied in the debug version.
|
||||
*/
|
||||
static inline SkPMColor SkPackARGB32NoCheck(U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
|
||||
return (a << SK_A32_SHIFT) | (r << SK_R32_SHIFT) |
|
||||
(g << SK_G32_SHIFT) | (b << SK_B32_SHIFT);
|
||||
return SkPackARGB_as_PMColor(a, r, g, b);
|
||||
}
|
||||
|
||||
static inline
|
||||
|
||||
@@ -82,8 +82,13 @@ enum SkColorType {
|
||||
kN32_SkColorType = kBGRA_8888_SkColorType,
|
||||
#elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A)
|
||||
kN32_SkColorType = kRGBA_8888_SkColorType,
|
||||
#elif defined(MOZ_SKIA) && SK_PMCOLOR_BYTE_ORDER(A,R,G,B)
|
||||
// Big-endian PowerPC Mozilla surfaces use native uint32 ARGB memory.
|
||||
// Moz2D's legacy A8R8G8B8_UINT32 format aliases to B8G8R8A8, so keep
|
||||
// kN32 on Skia's BGRA path while the channel shifts above describe ARGB.
|
||||
kN32_SkColorType = kBGRA_8888_SkColorType,
|
||||
#else
|
||||
#error "SK_*32_SHFIT values must correspond to BGRA or RGBA byte order"
|
||||
#error "SK_*32_SHIFT values must correspond to BGRA, RGBA, or Mozilla ARGB byte order"
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -275,17 +275,19 @@ enum GrPixelConfig {
|
||||
static const int kGrPixelConfigCnt = kLast_GrPixelConfig + 1;
|
||||
|
||||
// Aliases for pixel configs that match skia's byte order.
|
||||
#ifndef SK_CPU_LENDIAN
|
||||
#error "Skia gpu currently assumes little endian"
|
||||
#endif
|
||||
#if SK_PMCOLOR_BYTE_ORDER(B,G,R,A)
|
||||
static const GrPixelConfig kSkia8888_GrPixelConfig = kBGRA_8888_GrPixelConfig;
|
||||
static const GrPixelConfig kSkiaGamma8888_GrPixelConfig = kSBGRA_8888_GrPixelConfig;
|
||||
#elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A)
|
||||
static const GrPixelConfig kSkia8888_GrPixelConfig = kRGBA_8888_GrPixelConfig;
|
||||
static const GrPixelConfig kSkiaGamma8888_GrPixelConfig = kSRGBA_8888_GrPixelConfig;
|
||||
#elif defined(MOZ_SKIA) && SK_PMCOLOR_BYTE_ORDER(A,R,G,B)
|
||||
// Mozilla's big-endian PowerPC path stores native 32-bit pixels as ARGB,
|
||||
// while Moz2D routes those surfaces through Skia's BGRA color type.
|
||||
static const GrPixelConfig kSkia8888_GrPixelConfig = kBGRA_8888_GrPixelConfig;
|
||||
static const GrPixelConfig kSkiaGamma8888_GrPixelConfig = kSBGRA_8888_GrPixelConfig;
|
||||
#else
|
||||
#error "SK_*32_SHIFT values must correspond to GL_BGRA or GL_RGBA format."
|
||||
#error "SK_*32_SHIFT values must correspond to GL_BGRA, GL_RGBA, or Mozilla ARGB format."
|
||||
#endif
|
||||
|
||||
// Returns true if the pixel config is a GPU-specific compressed format
|
||||
|
||||
@@ -306,7 +306,11 @@ static inline SkPMColor premultiply_argb_as_bgra(U8CPU a, U8CPU r, U8CPU g, U8CP
|
||||
b = SkMulDiv255Round(b, a);
|
||||
}
|
||||
|
||||
#ifdef SK_PMCOLOR_IS_ARGB
|
||||
return SkPackARGB_as_PMColor(a, r, g, b);
|
||||
#else
|
||||
return SkPackARGB_as_BGRA(a, r, g, b);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline bool is_rgba(SkColorType colorType) {
|
||||
|
||||
@@ -51,10 +51,16 @@ struct SkPM4f {
|
||||
Sk4f to4f_pmorder() const { return swizzle_rb_if_bgra(this->to4f()); }
|
||||
|
||||
SkPMColor toPMColor() const {
|
||||
#ifdef SK_PMCOLOR_IS_ARGB
|
||||
Sk4f value = this->to4f();
|
||||
Sk4b bytes = SkNx_cast<uint8_t>(value * Sk4f(255) + Sk4f(0.5f));
|
||||
return SkPackARGB_as_PMColor(bytes[3], bytes[0], bytes[1], bytes[2]);
|
||||
#else
|
||||
Sk4f value = swizzle_rb_if_bgra(this->to4f());
|
||||
SkPMColor result;
|
||||
SkNx_cast<uint8_t>(value * Sk4f(255) + Sk4f(0.5f)).store(&result);
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
void toF16(uint16_t[4]) const;
|
||||
|
||||
@@ -22,29 +22,50 @@ static inline float get_alpha(const Sk4f& px) {
|
||||
|
||||
|
||||
static inline Sk4f Sk4f_fromL32(uint32_t px) {
|
||||
#ifdef SK_PMCOLOR_IS_ARGB
|
||||
return Sk4f(SkGetPackedR32(px), SkGetPackedG32(px),
|
||||
SkGetPackedB32(px), SkGetPackedA32(px)) * (1/255.0f);
|
||||
#else
|
||||
return SkNx_cast<float>(Sk4b::Load(&px)) * (1/255.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline Sk4f Sk4f_fromS32(uint32_t px) {
|
||||
#ifdef SK_PMCOLOR_IS_ARGB
|
||||
return { sk_linear_from_srgb[SkGetPackedR32(px)],
|
||||
sk_linear_from_srgb[SkGetPackedG32(px)],
|
||||
sk_linear_from_srgb[SkGetPackedB32(px)],
|
||||
(1/255.0f) * SkGetPackedA32(px) };
|
||||
#else
|
||||
return { sk_linear_from_srgb[(px >> 0) & 0xff],
|
||||
sk_linear_from_srgb[(px >> 8) & 0xff],
|
||||
sk_linear_from_srgb[(px >> 16) & 0xff],
|
||||
(1/255.0f) * (px >> 24) };
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline uint32_t Sk4f_toL32(const Sk4f& px) {
|
||||
#ifdef SK_PMCOLOR_IS_ARGB
|
||||
Sk4b bytes = SkNx_cast<uint8_t>(Sk4f_round(px * 255.0f));
|
||||
return SkPackARGB_as_PMColor(bytes[3], bytes[0], bytes[1], bytes[2]);
|
||||
#else
|
||||
uint32_t l32;
|
||||
SkNx_cast<uint8_t>(Sk4f_round(px * 255.0f)).store(&l32);
|
||||
return l32;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline uint32_t Sk4f_toS32(const Sk4f& px) {
|
||||
Sk4i rgb = sk_linear_to_srgb(px),
|
||||
srgb = { rgb[0], rgb[1], rgb[2], (int)(255.0f * px[3] + 0.5f) };
|
||||
|
||||
#ifdef SK_PMCOLOR_IS_ARGB
|
||||
return SkPackARGB_as_PMColor(srgb[3], srgb[0], srgb[1], srgb[2]);
|
||||
#else
|
||||
uint32_t s32;
|
||||
SkNx_cast<uint8_t>(srgb).store(&s32);
|
||||
return s32;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -121,9 +121,10 @@ SkDEBUGCODE(static const unsigned kRunRecordMagic = 0xb10bcafe;)
|
||||
namespace {
|
||||
struct RunRecordStorageEquivalent {
|
||||
RunFont fFont;
|
||||
SkPoint fOffset;
|
||||
uint32_t fCount;
|
||||
uint32_t fFlags;
|
||||
SkPoint fOffset;
|
||||
SkTextBlob::GlyphPositioning fPositioning;
|
||||
bool fExtended;
|
||||
SkDEBUGCODE(unsigned fMagic;)
|
||||
};
|
||||
}
|
||||
|
||||
@@ -44,6 +44,25 @@ static Sk4x4f load_4_srgb(const void* vptr) {
|
||||
|
||||
Sk4x4f rgba;
|
||||
|
||||
#ifdef SK_PMCOLOR_IS_ARGB
|
||||
rgba.r = { sk_linear_from_srgb[SkGetPackedR32(ptr[0])],
|
||||
sk_linear_from_srgb[SkGetPackedR32(ptr[1])],
|
||||
sk_linear_from_srgb[SkGetPackedR32(ptr[2])],
|
||||
sk_linear_from_srgb[SkGetPackedR32(ptr[3])] };
|
||||
|
||||
rgba.g = { sk_linear_from_srgb[SkGetPackedG32(ptr[0])],
|
||||
sk_linear_from_srgb[SkGetPackedG32(ptr[1])],
|
||||
sk_linear_from_srgb[SkGetPackedG32(ptr[2])],
|
||||
sk_linear_from_srgb[SkGetPackedG32(ptr[3])] };
|
||||
|
||||
rgba.b = { sk_linear_from_srgb[SkGetPackedB32(ptr[0])],
|
||||
sk_linear_from_srgb[SkGetPackedB32(ptr[1])],
|
||||
sk_linear_from_srgb[SkGetPackedB32(ptr[2])],
|
||||
sk_linear_from_srgb[SkGetPackedB32(ptr[3])] };
|
||||
|
||||
rgba.a = SkNx_cast<float>(Sk4i(SkGetPackedA32(ptr[0]), SkGetPackedA32(ptr[1]),
|
||||
SkGetPackedA32(ptr[2]), SkGetPackedA32(ptr[3]))) * (1/255.0f);
|
||||
#else
|
||||
rgba.r = { sk_linear_from_srgb[(ptr[0] >> 0) & 0xff],
|
||||
sk_linear_from_srgb[(ptr[1] >> 0) & 0xff],
|
||||
sk_linear_from_srgb[(ptr[2] >> 0) & 0xff],
|
||||
@@ -60,15 +79,28 @@ static Sk4x4f load_4_srgb(const void* vptr) {
|
||||
sk_linear_from_srgb[(ptr[3] >> 16) & 0xff] };
|
||||
|
||||
rgba.a = SkNx_cast<float>((Sk4i::Load(ptr) >> 24) & 0xff) * (1/255.0f);
|
||||
#endif
|
||||
|
||||
return rgba;
|
||||
}
|
||||
|
||||
static void store_4_srgb(void* ptr, const Sk4x4f& p) {
|
||||
#ifdef SK_PMCOLOR_IS_ARGB
|
||||
uint32_t* dst = (uint32_t*)ptr;
|
||||
Sk4i r = sk_linear_to_srgb(p.r);
|
||||
Sk4i g = sk_linear_to_srgb(p.g);
|
||||
Sk4i b = sk_linear_to_srgb(p.b);
|
||||
Sk4i a = Sk4f_round(255.0f*p.a);
|
||||
dst[0] = SkPackARGB_as_PMColor(a[0], r[0], g[0], b[0]);
|
||||
dst[1] = SkPackARGB_as_PMColor(a[1], r[1], g[1], b[1]);
|
||||
dst[2] = SkPackARGB_as_PMColor(a[2], r[2], g[2], b[2]);
|
||||
dst[3] = SkPackARGB_as_PMColor(a[3], r[3], g[3], b[3]);
|
||||
#else
|
||||
( sk_linear_to_srgb(p.r) << 0
|
||||
| sk_linear_to_srgb(p.g) << 8
|
||||
| sk_linear_to_srgb(p.b) << 16
|
||||
| Sk4f_round(255.0f*p.a) << 24).store(ptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -391,7 +423,7 @@ SkXfermode::D32Proc SkXfermode::GetD32Proc(SkXfermode* xfer, uint32_t flags) {
|
||||
#include "SkColorPriv.h"
|
||||
|
||||
static Sk4f lcd16_to_unit_4f(uint16_t rgb) {
|
||||
#ifdef SK_PMCOLOR_IS_RGBA
|
||||
#if defined(SK_PMCOLOR_IS_RGBA) || defined(SK_PMCOLOR_IS_ARGB)
|
||||
Sk4i rgbi = Sk4i(SkGetPackedR16(rgb), SkGetPackedG16(rgb), SkGetPackedB16(rgb), 0);
|
||||
#else
|
||||
Sk4i rgbi = Sk4i(SkGetPackedB16(rgb), SkGetPackedG16(rgb), SkGetPackedR16(rgb), 0);
|
||||
|
||||
@@ -251,7 +251,7 @@ bool GrDrawTarget::drawBatches(GrBatchFlushState* flushState) {
|
||||
if (currentRT) {
|
||||
static const GrGpuCommandBuffer::LoadAndStoreInfo kBasicLoadStoreInfo
|
||||
{ GrGpuCommandBuffer::LoadOp::kLoad,GrGpuCommandBuffer::StoreOp::kStore,
|
||||
GrColor_ILLEGAL };
|
||||
static_cast<GrColor>(GrColor_ILLEGAL) };
|
||||
commandBuffer.reset(fGpu->createCommandBuffer(currentRT,
|
||||
kBasicLoadStoreInfo, // Color
|
||||
kBasicLoadStoreInfo)); // Stencil
|
||||
|
||||
@@ -69,11 +69,18 @@ inline Sk4px Sk4px::Wide::div255() const {
|
||||
}
|
||||
|
||||
inline Sk4px Sk4px::alphas() const {
|
||||
#ifdef SK_PMCOLOR_IS_ARGB
|
||||
return Sk16b((*this)[ 0], (*this)[ 0], (*this)[ 0], (*this)[ 0],
|
||||
(*this)[ 4], (*this)[ 4], (*this)[ 4], (*this)[ 4],
|
||||
(*this)[ 8], (*this)[ 8], (*this)[ 8], (*this)[ 8],
|
||||
(*this)[12], (*this)[12], (*this)[12], (*this)[12]);
|
||||
#else
|
||||
static_assert(SK_A32_SHIFT == 24, "This method assumes little-endian.");
|
||||
return Sk16b((*this)[ 3], (*this)[ 3], (*this)[ 3], (*this)[ 3],
|
||||
(*this)[ 7], (*this)[ 7], (*this)[ 7], (*this)[ 7],
|
||||
(*this)[11], (*this)[11], (*this)[11], (*this)[11],
|
||||
(*this)[15], (*this)[15], (*this)[15], (*this)[15]);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline Sk4px Sk4px::Load4Alphas(const SkAlpha a[4]) {
|
||||
@@ -91,19 +98,33 @@ inline Sk4px Sk4px::Load2Alphas(const SkAlpha a[2]) {
|
||||
}
|
||||
|
||||
inline Sk4px Sk4px::zeroAlphas() const {
|
||||
#ifdef SK_PMCOLOR_IS_ARGB
|
||||
return Sk16b(0, (*this)[ 1], (*this)[ 2], (*this)[ 3],
|
||||
0, (*this)[ 5], (*this)[ 6], (*this)[ 7],
|
||||
0, (*this)[ 9], (*this)[10], (*this)[11],
|
||||
0, (*this)[13], (*this)[14], (*this)[15]);
|
||||
#else
|
||||
static_assert(SK_A32_SHIFT == 24, "This method assumes little-endian.");
|
||||
return Sk16b((*this)[ 0], (*this)[ 1], (*this)[ 2], 0,
|
||||
(*this)[ 4], (*this)[ 5], (*this)[ 6], 0,
|
||||
(*this)[ 8], (*this)[ 9], (*this)[10], 0,
|
||||
(*this)[12], (*this)[13], (*this)[14], 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline Sk4px Sk4px::zeroColors() const {
|
||||
#ifdef SK_PMCOLOR_IS_ARGB
|
||||
return Sk16b((*this)[ 0], 0,0,0,
|
||||
(*this)[ 4], 0,0,0,
|
||||
(*this)[ 8], 0,0,0,
|
||||
(*this)[12], 0,0,0);
|
||||
#else
|
||||
static_assert(SK_A32_SHIFT == 24, "This method assumes little-endian.");
|
||||
return Sk16b(0,0,0, (*this)[ 3],
|
||||
0,0,0, (*this)[ 7],
|
||||
0,0,0, (*this)[11],
|
||||
0,0,0, (*this)[15]);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -72,6 +72,10 @@ static void color_cube_filter_span(const SkPMColor src[],
|
||||
// color is BGRA (SkColor order), dst is SkPMColor order, so may need to swap R+B.
|
||||
#if defined(SK_PMCOLOR_IS_RGBA)
|
||||
color = SkNx_shuffle<2,1,0,3>(color);
|
||||
#elif defined(SK_PMCOLOR_IS_ARGB)
|
||||
Sk4b bytes = SkNx_cast<uint8_t>(color);
|
||||
dst[i] = SkPackARGB32NoCheck(a, bytes[2], bytes[1], bytes[0]);
|
||||
continue;
|
||||
#endif
|
||||
uint8_t* dstBytes = (uint8_t*)(dst+i);
|
||||
SkNx_cast<uint8_t>(color).store(dstBytes);
|
||||
|
||||
@@ -73,7 +73,39 @@ static CFArrayRef SkCTFontManagerCopyAvailableFontFamilyNames() {
|
||||
#ifdef SK_BUILD_FOR_IOS
|
||||
return CFArrayCreate(nullptr, nullptr, 0, nullptr);
|
||||
#else
|
||||
#if defined(MAC_OS_X_VERSION_10_6) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
|
||||
return CTFontManagerCopyAvailableFontFamilyNames();
|
||||
#else
|
||||
CFMutableArrayRef familyNames =
|
||||
CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
|
||||
if (!familyNames) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ATSFontFamilyIterator iterator;
|
||||
OSStatus status = ATSFontFamilyIteratorCreate(kATSFontContextGlobal,
|
||||
nullptr,
|
||||
nullptr,
|
||||
kATSOptionFlagsDefaultScope,
|
||||
&iterator);
|
||||
if (status != noErr) {
|
||||
CFRelease(familyNames);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ATSFontFamilyRef family;
|
||||
while (ATSFontFamilyIteratorNext(iterator, &family) == noErr) {
|
||||
CFStringRef familyName = nullptr;
|
||||
if (ATSFontFamilyGetName(family, kATSOptionFlagsDefault, &familyName) == noErr &&
|
||||
familyName) {
|
||||
CFArrayAppendValue(familyNames, familyName);
|
||||
CFRelease(familyName);
|
||||
}
|
||||
}
|
||||
|
||||
ATSFontFamilyIteratorRelease(&iterator);
|
||||
return familyNames;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -908,6 +940,7 @@ CGRGBPixel* Offscreen::getCG(const SkScalerContext_Mac& context, const SkGlyph&
|
||||
|
||||
// Skia handles quantization and subpixel positioning,
|
||||
// so disable quantization and enabe subpixel positioning in CG.
|
||||
#if defined(MAC_OS_X_VERSION_10_6) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
|
||||
CGContextSetAllowsFontSubpixelQuantization(fCG, false);
|
||||
CGContextSetShouldSubpixelQuantizeFonts(fCG, false);
|
||||
|
||||
@@ -916,6 +949,7 @@ CGRGBPixel* Offscreen::getCG(const SkScalerContext_Mac& context, const SkGlyph&
|
||||
// then CG cannot draw the glyph in the correct location without subpixel positioning.
|
||||
CGContextSetAllowsFontSubpixelPositioning(fCG, true);
|
||||
CGContextSetShouldSubpixelPositionFonts(fCG, true);
|
||||
#endif
|
||||
|
||||
CGContextSetTextDrawingMode(fCG, kCGTextFill);
|
||||
|
||||
@@ -971,7 +1005,13 @@ CGRGBPixel* Offscreen::getCG(const SkScalerContext_Mac& context, const SkGlyph&
|
||||
// So always make the font transform identity and place the transform on the context.
|
||||
point = CGPointApplyAffineTransform(point, context.fInvTransform);
|
||||
|
||||
#if defined(MAC_OS_X_VERSION_10_7) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7)
|
||||
CTFontDrawGlyphs(context.fCTFont, &glyphID, &point, 1, fCG);
|
||||
#else
|
||||
CGContextSetFont(fCG, CTFontCopyGraphicsFont(context.fCTFont, NULL));
|
||||
CGContextSetFontSize(fCG, CTFontGetSize(context.fCTFont));
|
||||
CGContextShowGlyphsAtPositions(fCG, &glyphID, &point, 1);
|
||||
#endif
|
||||
|
||||
SkASSERT(rowBytesPtr);
|
||||
*rowBytesPtr = rowBytes;
|
||||
@@ -1682,6 +1722,7 @@ SkAdvancedTypefaceMetrics* SkTypeface_Mac::onGetAdvancedTypefaceMetrics(
|
||||
|
||||
static SK_SFNT_ULONG get_font_type_tag(const SkTypeface_Mac* typeface) {
|
||||
CTFontRef ctFont = typeface->fFontRef.get();
|
||||
#if defined(MAC_OS_X_VERSION_10_6) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
|
||||
AutoCFRelease<CFNumberRef> fontFormatRef(
|
||||
static_cast<CFNumberRef>(CTFontCopyAttribute(ctFont, kCTFontFormatAttribute)));
|
||||
if (!fontFormatRef) {
|
||||
@@ -1711,6 +1752,35 @@ static SK_SFNT_ULONG get_font_type_tag(const SkTypeface_Mac* typeface) {
|
||||
//Just the presence of the FontForge 'FFTM' table seems to throw it off.
|
||||
return SkSFNTHeader::fontType_WindowsTrueType::TAG;
|
||||
}
|
||||
#else
|
||||
AutoCFRelease<CFStringRef> postScriptName(CTFontCopyPostScriptName(ctFont));
|
||||
if (!postScriptName) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ATSFontRef atsFont =
|
||||
ATSFontFindFromPostScriptName(postScriptName, kATSOptionFlagsDefault);
|
||||
if (atsFont == kInvalidFont) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
SkSFNTHeader header;
|
||||
ByteCount headerSize = sizeof(header);
|
||||
if (ATSFontGetTableDirectory(atsFont, headerSize, &header, &headerSize) != noErr ||
|
||||
headerSize < sizeof(header.fontType)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (header.fontType) {
|
||||
case SkSFNTHeader::fontType_OpenTypeCFF::TAG:
|
||||
case SkSFNTHeader::fontType_WindowsTrueType::TAG:
|
||||
case SkSFNTHeader::fontType_MacTrueType::TAG:
|
||||
case SkSFNTHeader::fontType_PostScript::TAG:
|
||||
return header.fontType;
|
||||
default:
|
||||
return SkSFNTHeader::fontType_WindowsTrueType::TAG;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
SkStreamAsset* SkTypeface_Mac::onOpenStream(int* ttcIndex) const {
|
||||
|
||||
@@ -66,10 +66,28 @@ struct WeakCell {
|
||||
WeakCellKind kind;
|
||||
WeakRef<JSObject*> object;
|
||||
WeakRef<JS::Symbol*> symbol;
|
||||
bool enabled;
|
||||
|
||||
WeakCell() : kind(WeakCellKind::Empty), object(nullptr), symbol(nullptr) {}
|
||||
explicit WeakCell(JSObject* obj) : kind(WeakCellKind::Object), object(obj), symbol(nullptr) {}
|
||||
explicit WeakCell(JS::Symbol* sym) : kind(WeakCellKind::Symbol), object(nullptr), symbol(sym) {}
|
||||
WeakCell()
|
||||
: kind(WeakCellKind::Empty)
|
||||
, object(nullptr)
|
||||
, symbol(nullptr)
|
||||
, enabled(true)
|
||||
{}
|
||||
|
||||
explicit WeakCell(JSObject* obj, bool enabled)
|
||||
: kind(WeakCellKind::Object)
|
||||
, object(obj)
|
||||
, symbol(nullptr)
|
||||
, enabled(enabled)
|
||||
{}
|
||||
|
||||
explicit WeakCell(JS::Symbol* sym, bool enabled)
|
||||
: kind(WeakCellKind::Symbol)
|
||||
, object(nullptr)
|
||||
, symbol(sym)
|
||||
, enabled(enabled)
|
||||
{}
|
||||
|
||||
void clear() {
|
||||
kind = WeakCellKind::Empty;
|
||||
@@ -101,7 +119,9 @@ struct WeakCell {
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
if (IsInsideNursery(target)) {
|
||||
if (!enabled) {
|
||||
// Do nothing
|
||||
} else if (IsInsideNursery(target)) {
|
||||
TraceManuallyBarrieredEdge(trc, object.unsafeGet(), name);
|
||||
} else {
|
||||
if (trc->isMarkingTracer() && !target->asTenured().zone()->isCollecting())
|
||||
@@ -110,7 +130,7 @@ struct WeakCell {
|
||||
}
|
||||
} else if (kind == WeakCellKind::Symbol) {
|
||||
JS::Symbol* target = symbol.unbarrieredGet();
|
||||
if (target) {
|
||||
if (enabled && target) {
|
||||
if (trc->isMarkingTracer() && !target->asTenured().zone()->isCollecting())
|
||||
return;
|
||||
TraceWeakEdge(trc, &symbol, name);
|
||||
@@ -124,14 +144,16 @@ struct WeakCell {
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
if (IsInsideNursery(target)) {
|
||||
if (!enabled) {
|
||||
// Do nothing
|
||||
} else if (IsInsideNursery(target)) {
|
||||
TraceManuallyBarrieredEdge(trc, object.unsafeGet(), name);
|
||||
} else if (target->asTenured().zone()->isCollecting()) {
|
||||
TraceWeakEdge(trc, &object, name);
|
||||
}
|
||||
} else if (kind == WeakCellKind::Symbol) {
|
||||
JS::Symbol* target = symbol.unbarrieredGet();
|
||||
if (target && target->asTenured().zone()->isCollecting())
|
||||
if (enabled && target && target->asTenured().zone()->isCollecting())
|
||||
TraceWeakEdge(trc, &symbol, name);
|
||||
}
|
||||
}
|
||||
@@ -143,22 +165,24 @@ struct FinalizationRecord {
|
||||
WeakCell unregisterToken;
|
||||
bool active;
|
||||
bool queued;
|
||||
bool enabled;
|
||||
|
||||
FinalizationRecord(HandleValue targetValue, HandleValue heldValue,
|
||||
HandleValue unregisterTokenValue)
|
||||
HandleValue unregisterTokenValue, bool enabled)
|
||||
: heldValue(heldValue),
|
||||
active(true),
|
||||
queued(false)
|
||||
queued(false),
|
||||
enabled(enabled)
|
||||
{
|
||||
if (targetValue.isObject())
|
||||
target = WeakCell(NormalizeWeakObject(&targetValue.toObject()));
|
||||
target = WeakCell(NormalizeWeakObject(&targetValue.toObject()), enabled);
|
||||
else
|
||||
target = WeakCell(targetValue.toSymbol());
|
||||
target = WeakCell(targetValue.toSymbol(), enabled);
|
||||
|
||||
if (unregisterTokenValue.isObject())
|
||||
unregisterToken = WeakCell(NormalizeWeakObject(&unregisterTokenValue.toObject()));
|
||||
unregisterToken = WeakCell(NormalizeWeakObject(&unregisterTokenValue.toObject()), enabled);
|
||||
else if (unregisterTokenValue.isSymbol())
|
||||
unregisterToken = WeakCell(unregisterTokenValue.toSymbol());
|
||||
unregisterToken = WeakCell(unregisterTokenValue.toSymbol(), enabled);
|
||||
}
|
||||
|
||||
void trace(JSTracer* trc) {
|
||||
@@ -217,13 +241,15 @@ struct FinalizationRegistryObject::Data {
|
||||
FinalizationRecordVector records;
|
||||
FinalizationRecordVector cleanupQueue;
|
||||
bool queuedForCleanup;
|
||||
bool enabled;
|
||||
|
||||
explicit Data(JSObject* cleanupCallback)
|
||||
explicit Data(JSObject* cleanupCallback, bool enabled)
|
||||
: cleanupCallback(cleanupCallback),
|
||||
cleanupJob(nullptr),
|
||||
records(SystemAllocPolicy()),
|
||||
cleanupQueue(SystemAllocPolicy()),
|
||||
queuedForCleanup(false)
|
||||
queuedForCleanup(false),
|
||||
enabled(enabled)
|
||||
{}
|
||||
|
||||
~Data() {
|
||||
@@ -232,11 +258,13 @@ struct FinalizationRegistryObject::Data {
|
||||
}
|
||||
|
||||
void trace(JSTracer* trc) {
|
||||
JS::TraceEdge(trc, &cleanupCallback, "FinalizationRegistry cleanup callback");
|
||||
if (cleanupJob.unbarrieredGet())
|
||||
JS::TraceEdge(trc, &cleanupJob, "FinalizationRegistry cleanup job");
|
||||
for (size_t i = 0; i < records.length(); i++)
|
||||
records[i]->trace(trc);
|
||||
if (enabled) {
|
||||
JS::TraceEdge(trc, &cleanupCallback, "FinalizationRegistry cleanup callback");
|
||||
if (cleanupJob.unbarrieredGet())
|
||||
JS::TraceEdge(trc, &cleanupJob, "FinalizationRegistry cleanup job");
|
||||
for (size_t i = 0; i < records.length(); i++)
|
||||
records[i]->trace(trc);
|
||||
}
|
||||
}
|
||||
|
||||
bool appendRecord(FinalizationRecord* record) {
|
||||
@@ -317,7 +345,7 @@ FinalizationRegistry_register_impl(JSContext* cx, const CallArgs& args)
|
||||
unregisterToken.setUndefined();
|
||||
}
|
||||
|
||||
FinalizationRecord* record = cx->new_<FinalizationRecord>(target, heldValue, unregisterToken);
|
||||
FinalizationRecord* record = cx->new_<FinalizationRecord>(target, heldValue, unregisterToken, cx->options().weakRefs());
|
||||
if (!record)
|
||||
return false;
|
||||
|
||||
@@ -401,7 +429,7 @@ FinalizationRegistryObject::create(JSContext* cx, HandleObject cleanupCallback,
|
||||
if (!obj)
|
||||
return nullptr;
|
||||
|
||||
Data* data = cx->new_<Data>(cleanupCallback);
|
||||
Data* data = cx->new_<Data>(cleanupCallback, cx->options().weakRefs());
|
||||
if (!data)
|
||||
return nullptr;
|
||||
|
||||
|
||||
@@ -140,9 +140,9 @@ WeakRefObject::create(JSContext* cx, HandleValue target, HandleObject proto /* =
|
||||
|
||||
Referent* data;
|
||||
if (target.isObject())
|
||||
data = cx->new_<Referent>(&target.toObject());
|
||||
data = cx->new_<Referent>(&target.toObject(), cx->options().weakRefs());
|
||||
else
|
||||
data = cx->new_<Referent>(target.toSymbol());
|
||||
data = cx->new_<Referent>(target.toSymbol(), cx->options().weakRefs());
|
||||
|
||||
if (!data)
|
||||
return nullptr;
|
||||
@@ -210,7 +210,9 @@ WeakRefObject::trace(JSTracer* trc, JSObject* obj)
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
if (IsInsideNursery(target)) {
|
||||
if (!data->enabled) {
|
||||
// Pref disabled, don't do anything.
|
||||
} else if (IsInsideNursery(target)) {
|
||||
// Weak edges must be tenured; trace strongly while referent is in the nursery.
|
||||
TraceManuallyBarrieredEdge(trc, data->objectTarget.unsafeGet(),
|
||||
"WeakRef nursery referent");
|
||||
@@ -220,7 +222,7 @@ WeakRefObject::trace(JSTracer* trc, JSObject* obj)
|
||||
} else {
|
||||
MOZ_ASSERT(data->isSymbol());
|
||||
JS::Symbol* target = data->symbolTarget.unbarrieredGet();
|
||||
if (target)
|
||||
if (data->enabled && target)
|
||||
TraceWeakEdge(trc, &data->symbolTarget, "WeakRef symbol referent");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,17 +22,27 @@ class WeakRefObject : public NativeObject
|
||||
Symbol
|
||||
};
|
||||
|
||||
explicit Referent(JSObject* obj)
|
||||
: kind(Kind::Object), objectTarget(obj), symbolTarget(nullptr) {}
|
||||
explicit Referent(JS::Symbol* sym)
|
||||
: kind(Kind::Symbol), objectTarget(nullptr), symbolTarget(sym) {}
|
||||
|
||||
explicit Referent(JSObject* obj, bool enabled)
|
||||
: kind(Kind::Object)
|
||||
, objectTarget(obj)
|
||||
, symbolTarget(nullptr)
|
||||
, enabled(enabled)
|
||||
{}
|
||||
|
||||
explicit Referent(JS::Symbol* sym, bool enabled)
|
||||
: kind(Kind::Symbol)
|
||||
, objectTarget(nullptr)
|
||||
, symbolTarget(sym)
|
||||
, enabled(enabled)
|
||||
{}
|
||||
|
||||
bool isObject() const { return kind == Kind::Object; }
|
||||
bool isSymbol() const { return kind == Kind::Symbol; }
|
||||
|
||||
Kind kind;
|
||||
WeakRef<JSObject*> objectTarget;
|
||||
WeakRef<JS::Symbol*> symbolTarget;
|
||||
bool enabled;
|
||||
};
|
||||
|
||||
static const Class class_;
|
||||
|
||||
+10
-10
@@ -416,13 +416,13 @@ MapMemoryAt(void* desired, size_t length, int prot = PROT_READ | PROT_WRITE,
|
||||
int flags = MAP_PRIVATE | MAP_ANON, int fd = -1, off_t offset = 0)
|
||||
|
||||
// Solaris manages 64-bit address space in a different manner from every other
|
||||
// AMD64 operating system, but fortunately the fix is the same one
|
||||
// required for every operating system on 64-bit SPARC, Itanium, and ARM.
|
||||
// AMD64 operating system, but fortunately the fix is the same one
|
||||
// required for every operating system on 64-bit SPARC and ARM.
|
||||
// Most people's intuition failed them here and they thought this couldn't
|
||||
// possibly be correct on AMD64, but for Solaris/illumos it is.
|
||||
|
||||
{
|
||||
#if defined(__ia64__) || defined(__aarch64__) || (defined(__sun) && defined(__x86_64__)) || (defined(__sparc__) && defined(__arch64__) && (defined(__NetBSD__) || defined(__linux__)))
|
||||
#if defined(__aarch64__) || (defined(__sun) && defined(__x86_64__)) || (defined(__sparc__) && defined(__arch64__) && (defined(__NetBSD__) || defined(__linux__)))
|
||||
MOZ_ASSERT((0xffff800000000000ULL & (uintptr_t(desired) + length - 1)) == 0);
|
||||
#endif
|
||||
void* region = mmap(desired, length, prot, flags, fd, offset);
|
||||
@@ -445,14 +445,14 @@ static inline void*
|
||||
MapMemory(size_t length, int prot = PROT_READ | PROT_WRITE,
|
||||
int flags = MAP_PRIVATE | MAP_ANON, int fd = -1, off_t offset = 0)
|
||||
{
|
||||
#if defined(__ia64__) || (defined(__sparc__) && defined(__arch64__) && defined(__NetBSD__))
|
||||
#if defined(__sparc__) && defined(__arch64__) && defined(__NetBSD__)
|
||||
/*
|
||||
* The JS engine assumes that all allocated pointers have their high 17 bits clear,
|
||||
* which ia64's mmap doesn't support directly. However, we can emulate it by passing
|
||||
* mmap an "addr" parameter with those bits clear. The mmap will return that address,
|
||||
* or the nearest available memory above that address, providing a near-guarantee
|
||||
* that those bits are clear. If they are not, we return nullptr below to indicate
|
||||
* out-of-memory.
|
||||
* which mmap on this platform doesn't support directly. However, we can emulate it
|
||||
* by passing mmap an "addr" parameter with those bits clear. The mmap will return
|
||||
* that address, or the nearest available memory above that address, providing a
|
||||
* near-guarantee that those bits are clear. If they are not, we return nullptr below
|
||||
* to indicate out-of-memory.
|
||||
*
|
||||
* The addr is chosen as 0x0000070000000000, which still allows about 120TB of virtual
|
||||
* address space.
|
||||
@@ -479,7 +479,7 @@ MapMemory(size_t length, int prot = PROT_READ | PROT_WRITE,
|
||||
* different due to the different mmap behavior.
|
||||
*
|
||||
* TODO: Merge with the above code block if this implementation works for
|
||||
* ia64 and sparc64.
|
||||
* sparc64.
|
||||
*/
|
||||
const uintptr_t start = UINT64_C(0x0000070000000000);
|
||||
const uintptr_t end = UINT64_C(0x0000800000000000);
|
||||
|
||||
@@ -8185,7 +8185,7 @@ CodeGenerator::visitStoreElementV(LStoreElementV* lir)
|
||||
template <typename T> void
|
||||
CodeGenerator::emitStoreElementHoleT(T* lir)
|
||||
{
|
||||
static_assert(std::is_same<T, LStoreElementHoleT>::value || std::is_same<T, LFallibleStoreElementT>::value,
|
||||
static_assert(std::is_same_v<T, LStoreElementHoleT> || std::is_same_v<T, LFallibleStoreElementT>,
|
||||
"emitStoreElementHoleT called with unexpected argument type");
|
||||
|
||||
OutOfLineStoreElementHole* ool = new(alloc()) OutOfLineStoreElementHole(lir);
|
||||
@@ -8244,7 +8244,7 @@ CodeGenerator::visitStoreElementHoleT(LStoreElementHoleT* lir)
|
||||
template <typename T> void
|
||||
CodeGenerator::emitStoreElementHoleV(T* lir)
|
||||
{
|
||||
static_assert(std::is_same<T, LStoreElementHoleV>::value || std::is_same<T, LFallibleStoreElementV>::value,
|
||||
static_assert(std::is_same_v<T, LStoreElementHoleV> || std::is_same_v<T, LFallibleStoreElementV>,
|
||||
"emitStoreElementHoleV called with unexpected parameter type");
|
||||
|
||||
OutOfLineStoreElementHole* ool = new(alloc()) OutOfLineStoreElementHole(lir);
|
||||
|
||||
@@ -320,7 +320,6 @@ size_t AssemblerLOONGARCH64::bytesNeeded() const {
|
||||
|
||||
// write a blob of binary into the instruction stream
|
||||
BufferOffset AssemblerLOONGARCH64::writeInst(uint32_t x, uint32_t* dest) {
|
||||
MOZ_ASSERT(hasCreator());
|
||||
if (dest == nullptr) {
|
||||
return m_buffer.putInt(x);
|
||||
}
|
||||
|
||||
@@ -212,6 +212,8 @@ static constexpr Register WasmTableCallIndexReg = ABINonArgReg3;
|
||||
static constexpr Register WasmIonExitRegCallee = t0;
|
||||
static constexpr Register WasmIonExitRegE0 = a0;
|
||||
static constexpr Register WasmIonExitRegE1 = a1;
|
||||
static constexpr Register WasmIonExitRegReturnData = JSReturnReg_Data;
|
||||
static constexpr Register WasmIonExitRegReturnType = JSReturnReg_Type;
|
||||
static constexpr Register WasmIonExitRegD0 = a0;
|
||||
static constexpr Register WasmIonExitRegD1 = a1;
|
||||
static constexpr Register WasmIonExitRegD2 = t0;
|
||||
|
||||
@@ -1013,8 +1013,8 @@ CodeGeneratorLoongArch64::visitTestI64AndBranch(LTestI64AndBranch* lir)
|
||||
void
|
||||
CodeGeneratorLoongArch64::setReturnDoubleRegs(LiveRegisterSet* regs)
|
||||
{
|
||||
MOZ_ASSERT(ReturnFloat32Reg.reg_ == FloatRegisters::f0);
|
||||
MOZ_ASSERT(ReturnDoubleReg.reg_ == FloatRegisters::f0);
|
||||
MOZ_ASSERT(ReturnFloat32Reg.encoding() == FloatRegisters::f0);
|
||||
MOZ_ASSERT(ReturnDoubleReg.encoding() == FloatRegisters::f0);
|
||||
FloatRegister f1 = { FloatRegisters::f1, FloatRegisters::Single };
|
||||
regs->add(ReturnFloat32Reg);
|
||||
regs->add(f1);
|
||||
|
||||
@@ -2395,7 +2395,7 @@ void MacroAssemblerLOONGARCH64::wasmLoadImpl(const wasm::MemoryAccessDesc& acces
|
||||
Register ptrScratch,
|
||||
AnyRegister output, Register tmp) {
|
||||
uint32_t offset = access.offset();
|
||||
MOZ_ASSERT(offset < asMasm().wasmMaxOffsetGuardLimit());
|
||||
MOZ_ASSERT(offset < wasm::OffsetGuardLimit);
|
||||
MOZ_ASSERT_IF(offset, ptrScratch != InvalidReg);
|
||||
|
||||
// Maybe add the offset.
|
||||
@@ -2442,7 +2442,7 @@ void MacroAssemblerLOONGARCH64::wasmStoreImpl(const wasm::MemoryAccessDesc& acce
|
||||
Register memoryBase, Register ptr,
|
||||
Register ptrScratch, Register tmp) {
|
||||
uint32_t offset = access.offset();
|
||||
MOZ_ASSERT(offset < asMasm().wasmMaxOffsetGuardLimit());
|
||||
MOZ_ASSERT(offset < wasm::OffsetGuardLimit);
|
||||
MOZ_ASSERT_IF(offset, ptrScratch != InvalidReg);
|
||||
|
||||
// Maybe add the offset.
|
||||
@@ -2488,7 +2488,7 @@ void MacroAssemblerLOONGARCH64Compat::wasmLoadI64Impl(
|
||||
const wasm::MemoryAccessDesc& access, Register memoryBase, Register ptr,
|
||||
Register ptrScratch, Register64 output, Register tmp) {
|
||||
uint32_t offset = access.offset();
|
||||
MOZ_ASSERT(offset < asMasm().wasmMaxOffsetGuardLimit());
|
||||
MOZ_ASSERT(offset < wasm::OffsetGuardLimit);
|
||||
MOZ_ASSERT_IF(offset, ptrScratch != InvalidReg);
|
||||
|
||||
// Maybe add the offset.
|
||||
@@ -2534,7 +2534,7 @@ void MacroAssemblerLOONGARCH64Compat::wasmStoreI64Impl(
|
||||
const wasm::MemoryAccessDesc& access, Register64 value, Register memoryBase,
|
||||
Register ptr, Register ptrScratch, Register tmp) {
|
||||
uint32_t offset = access.offset();
|
||||
MOZ_ASSERT(offset < asMasm().wasmMaxOffsetGuardLimit());
|
||||
MOZ_ASSERT(offset < wasm::OffsetGuardLimit);
|
||||
MOZ_ASSERT_IF(offset, ptrScratch != InvalidReg);
|
||||
|
||||
// Maybe add the offset.
|
||||
@@ -2774,12 +2774,13 @@ CodeOffset MacroAssembler::nopPatchableToNearJump() {
|
||||
}
|
||||
|
||||
void MacroAssembler::patchNopToNearJump(uint8_t* jump, uint8_t* target) {
|
||||
MOZ_ASSERT(reinterpret_cast<Instruction*>(jump)->is<InstNOP>());
|
||||
MOZ_ASSERT(reinterpret_cast<Instruction*>(jump)->encode() == NopInst);
|
||||
new (jump) InstJump(op_b, JOffImm26(target - jump));
|
||||
}
|
||||
|
||||
void MacroAssembler::patchNearJumpToNop(uint8_t* jump) {
|
||||
MOZ_ASSERT(reinterpret_cast<Instruction*>(jump)->is<InstJump>());
|
||||
MOZ_ASSERT(reinterpret_cast<Instruction*>(jump)->extractBitField(31, 26) ==
|
||||
(uint32_t)op_b >> 26);
|
||||
new (jump) InstNOP();
|
||||
}
|
||||
|
||||
|
||||
@@ -301,7 +301,7 @@ void unmapPages(void* p, size_t size) { }
|
||||
void*
|
||||
mapMemoryAt(void* desired, size_t length)
|
||||
{
|
||||
#if defined(__ia64__) || defined(__aarch64__) || \
|
||||
#if defined(__aarch64__) || \
|
||||
(defined(__sparc__) && defined(__arch64__) && (defined(__NetBSD__) || defined(__linux__)))
|
||||
MOZ_RELEASE_ASSERT(0xffff800000000000ULL & (uintptr_t(desired) + length - 1) == 0);
|
||||
#endif
|
||||
@@ -324,7 +324,7 @@ mapMemory(size_t length)
|
||||
int fd = -1;
|
||||
off_t offset = 0;
|
||||
// The test code must be aligned with the implementation in gc/Memory.cpp.
|
||||
#if defined(__ia64__) || (defined(__sparc__) && defined(__arch64__) && defined(__NetBSD__))
|
||||
#if defined(__sparc__) && defined(__arch64__) && defined(__NetBSD__)
|
||||
void* region = mmap((void*)0x0000070000000000, length, prot, flags, fd, offset);
|
||||
if (region == MAP_FAILED)
|
||||
return nullptr;
|
||||
|
||||
+6
-3
@@ -999,7 +999,8 @@ class JS_PUBLIC_API(ContextOptions) {
|
||||
strictMode_(false),
|
||||
extraWarnings_(false),
|
||||
arrayProtoValues_(true),
|
||||
streams_(false)
|
||||
streams_(false),
|
||||
weakRefs_(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1139,12 +1140,13 @@ class JS_PUBLIC_API(ContextOptions) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool weakRefs() const { return true; }
|
||||
bool weakRefs() const { return weakRefs_; }
|
||||
ContextOptions& setWeakRefs(bool flag) {
|
||||
(void) flag;
|
||||
weakRefs_ = flag;
|
||||
return *this;
|
||||
}
|
||||
ContextOptions& toggleWeakRefs() {
|
||||
weakRefs_ = !weakRefs_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -1165,6 +1167,7 @@ class JS_PUBLIC_API(ContextOptions) {
|
||||
bool extraWarnings_ : 1;
|
||||
bool arrayProtoValues_ : 1;
|
||||
bool streams_ : 1;
|
||||
bool weakRefs_ : 1;
|
||||
};
|
||||
|
||||
JS_PUBLIC_API(ContextOptions&)
|
||||
|
||||
+39
-11
@@ -976,6 +976,12 @@ CanUpperCaseSpecialCasing(Latin1Char charCode)
|
||||
static inline bool
|
||||
CanUpperCaseSpecialCasing(char16_t charCode)
|
||||
{
|
||||
// Update mapping for U+00DF LATIN SMALL LETTER SHARP S inline,
|
||||
// overriding Unicode data files to force the use of
|
||||
// U+1E9E LATIN CAPITAL LETTER SHARP S.
|
||||
if (charCode == unicode::LATIN_SMALL_LETTER_SHARP_S)
|
||||
return true;
|
||||
|
||||
return unicode::CanUpperCaseSpecialCasing(charCode);
|
||||
}
|
||||
|
||||
@@ -991,6 +997,11 @@ LengthUpperCaseSpecialCasing(Latin1Char charCode)
|
||||
static inline size_t
|
||||
LengthUpperCaseSpecialCasing(char16_t charCode)
|
||||
{
|
||||
// U+00DF LATIN SMALL LETTER SHARP S is uppercased according to ICU or
|
||||
// to U+1E9E LATIN CAPITAL LETTER SHARP S.
|
||||
if (charCode == unicode::LATIN_SMALL_LETTER_SHARP_S)
|
||||
return 1;
|
||||
|
||||
MOZ_ASSERT(CanUpperCaseSpecialCasing(charCode));
|
||||
|
||||
return unicode::LengthUpperCaseSpecialCasing(charCode);
|
||||
@@ -1010,6 +1021,13 @@ AppendUpperCaseSpecialCasing(char16_t charCode, Latin1Char* elements, size_t* in
|
||||
static inline void
|
||||
AppendUpperCaseSpecialCasing(char16_t charCode, char16_t* elements, size_t* index)
|
||||
{
|
||||
// U+00DF LATIN SMALL LETTER SHARP S is uppercased according to ICU or
|
||||
// to U+1E9E LATIN CAPITAL LETTER SHARP S.
|
||||
if (charCode == unicode::LATIN_SMALL_LETTER_SHARP_S) {
|
||||
elements[(*index)++] = 0x1E9E;
|
||||
return;
|
||||
}
|
||||
|
||||
unicode::AppendUpperCaseSpecialCasing(charCode, elements, index);
|
||||
}
|
||||
|
||||
@@ -1025,6 +1043,7 @@ ToUpperCaseImpl(DestChar* destChars, const SrcChar* srcChars, size_t startIndex,
|
||||
MOZ_ASSERT(srcLength <= destLength);
|
||||
|
||||
size_t j = startIndex;
|
||||
size_t upperLength = srcLength;
|
||||
for (size_t i = startIndex; i < srcLength; i++) {
|
||||
char16_t c = srcChars[i];
|
||||
if (!IsSame<DestChar, Latin1Char>::value) {
|
||||
@@ -1040,9 +1059,10 @@ ToUpperCaseImpl(DestChar* destChars, const SrcChar* srcChars, size_t startIndex,
|
||||
}
|
||||
}
|
||||
|
||||
if (MOZ_UNLIKELY(c > 0x7f && CanUpperCaseSpecialCasing(static_cast<SrcChar>(c)))) {
|
||||
if (MOZ_UNLIKELY(c > 0x7f && CanUpperCaseSpecialCasing(static_cast<DestChar>(c)))) {
|
||||
// Return if the output buffer is too small.
|
||||
if (srcLength == destLength)
|
||||
upperLength += (LengthUpperCaseSpecialCasing(static_cast<DestChar>(c)) - 1);
|
||||
if (upperLength > destLength)
|
||||
return i;
|
||||
|
||||
AppendUpperCaseSpecialCasing(c, destChars, &j);
|
||||
@@ -1071,14 +1091,18 @@ ToUpperCaseImpl(Latin1Char* destChars, const char16_t* srcChars, size_t startInd
|
||||
|
||||
template <typename CharT>
|
||||
static size_t
|
||||
ToUpperCaseLength(const CharT* chars, size_t startIndex, size_t length)
|
||||
ToUpperCaseLength(const CharT* chars, size_t startIndex, size_t length, bool force16)
|
||||
{
|
||||
size_t upperLength = length;
|
||||
for (size_t i = startIndex; i < length; i++) {
|
||||
char16_t c = chars[i];
|
||||
|
||||
if (c > 0x7f && CanUpperCaseSpecialCasing(static_cast<CharT>(c)))
|
||||
upperLength += LengthUpperCaseSpecialCasing(static_cast<CharT>(c)) - 1;
|
||||
if (c > 0x7f &&
|
||||
(force16 && CanUpperCaseSpecialCasing(c) ||
|
||||
CanUpperCaseSpecialCasing(static_cast<CharT>(c))))
|
||||
upperLength += (force16
|
||||
? LengthUpperCaseSpecialCasing(c)
|
||||
: LengthUpperCaseSpecialCasing(static_cast<CharT>(c))) - 1;
|
||||
}
|
||||
return upperLength;
|
||||
}
|
||||
@@ -1117,7 +1141,7 @@ ToUpperCase(JSContext* cx, const SrcChar* chars, size_t startIndex, size_t lengt
|
||||
|
||||
size_t readChars = ToUpperCaseImpl(buf.get(), chars, startIndex, length, length);
|
||||
if (readChars < length) {
|
||||
size_t actualLength = ToUpperCaseLength(chars, readChars, length);
|
||||
size_t actualLength = ToUpperCaseLength(chars, readChars, length, !IsSame<DestChar, Latin1Char>::value);
|
||||
|
||||
*resultLength = actualLength;
|
||||
DestCharPtr buf2 = ReallocChars(cx, Move(buf), length + 1, actualLength + 1);
|
||||
@@ -1178,7 +1202,8 @@ ToUpperCase(JSContext* cx, JSLinearString* str)
|
||||
//
|
||||
// If the original string is Latin-1, it can -- unless the string
|
||||
// contains U+00B5 MICRO SIGN or U+00FF SMALL LETTER Y WITH DIAERESIS,
|
||||
// the only Latin-1 codepoints that don't uppercase within Latin-1.
|
||||
// the only Latin-1 codepoints that don't uppercase within Latin-1, or
|
||||
// it contains U+00DF LATIN SMALL LETTER SHARP S, which we override.
|
||||
// Search for those codepoints to decide whether the new string can be
|
||||
// Latin-1.
|
||||
// If the original string is a two-byte string, its uppercase form is
|
||||
@@ -1195,6 +1220,9 @@ ToUpperCase(JSContext* cx, JSLinearString* str)
|
||||
MOZ_ASSERT(unicode::ToUpperCase(c) > JSString::MAX_LATIN1_CHAR);
|
||||
resultIsLatin1 = false;
|
||||
break;
|
||||
} else if (c == unicode::LATIN_SMALL_LETTER_SHARP_S) {
|
||||
resultIsLatin1 = false;
|
||||
break;
|
||||
} else {
|
||||
MOZ_ASSERT(unicode::ToUpperCase(c) <= JSString::MAX_LATIN1_CHAR);
|
||||
}
|
||||
@@ -2843,8 +2871,8 @@ static JSString* ReplaceAll(JSContext* cx, JSLinearString* str,
|
||||
|
||||
// Step 13.
|
||||
StringBuffer result(cx);
|
||||
if (std::is_same<StrChar, char16_t>::value ||
|
||||
std::is_same<RepChar, char16_t>::value) {
|
||||
if (std::is_same_v<StrChar, char16_t> ||
|
||||
std::is_same_v<RepChar, char16_t>) {
|
||||
if (!result.ensureTwoByteChars()) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -2926,8 +2954,8 @@ static JSString* ReplaceAllInterleave(JSContext* cx, JSLinearString* str,
|
||||
|
||||
// Step 13.
|
||||
StringBuffer result(cx);
|
||||
if (std::is_same<StrChar, char16_t>::value ||
|
||||
std::is_same<RepChar, char16_t>::value) {
|
||||
if (std::is_same_v<StrChar, char16_t> ||
|
||||
std::is_same_v<RepChar, char16_t>) {
|
||||
if (!result.ensureTwoByteChars()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -309,26 +309,26 @@ InflateUTF8StringToBuffer(ContextT* cx, const UTF8Chars src, CharT* dst, size_t*
|
||||
while (v & (0x80 >> n))
|
||||
n++;
|
||||
|
||||
#define INVALID(report, arg, n2) \
|
||||
do { \
|
||||
if (Action == CountAndReportInvalids) { \
|
||||
report(cx, arg); \
|
||||
return false; \
|
||||
} else if (Action == AssertNoInvalids) { \
|
||||
MOZ_CRASH("invalid UTF-8 string: " # report); \
|
||||
} else { \
|
||||
if (Action == Copy) { \
|
||||
if (std::is_same<decltype(dst[0]), Latin1Char>::value) \
|
||||
dst[j] = CharT(REPLACE_UTF8_LATIN1); \
|
||||
else \
|
||||
dst[j] = CharT(REPLACE_UTF8); \
|
||||
} else { \
|
||||
MOZ_ASSERT(Action == CountAndIgnoreInvalids || \
|
||||
Action == FindEncoding); \
|
||||
} \
|
||||
n = n2; \
|
||||
goto invalidMultiByteCodeUnit; \
|
||||
} \
|
||||
#define INVALID(report, arg, n2) \
|
||||
do { \
|
||||
if (Action == CountAndReportInvalids) { \
|
||||
report(cx, arg); \
|
||||
return false; \
|
||||
} else if (Action == AssertNoInvalids) { \
|
||||
MOZ_CRASH("invalid UTF-8 string: " # report); \
|
||||
} else { \
|
||||
if (Action == Copy) { \
|
||||
if (std::is_same_v<decltype(dst[0]), Latin1Char>) \
|
||||
dst[j] = CharT(REPLACE_UTF8_LATIN1); \
|
||||
else \
|
||||
dst[j] = CharT(REPLACE_UTF8); \
|
||||
} else { \
|
||||
MOZ_ASSERT(Action == CountAndIgnoreInvalids || \
|
||||
Action == FindEncoding); \
|
||||
} \
|
||||
n = n2; \
|
||||
goto invalidMultiByteCodeUnit; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
// Check the leading byte.
|
||||
|
||||
+1
-1
@@ -1138,7 +1138,7 @@ class StaticStrings
|
||||
}
|
||||
|
||||
template <typename CharT,
|
||||
typename = typename std::enable_if<!std::is_const<CharT>::value>::type>
|
||||
typename = typename std::enable_if_t<!std::is_const_v<CharT>>>
|
||||
MOZ_ALWAYS_INLINE JSAtom* lookup(CharT* chars, size_t length) {
|
||||
// Collapse the remaining |CharT*| to |const CharT*| to avoid excess
|
||||
// instantiations.
|
||||
|
||||
@@ -677,12 +677,12 @@ class ElementSpecific
|
||||
return true;
|
||||
}
|
||||
|
||||
if (std::is_same<T, int64_t>::value) {
|
||||
if (std::is_same_v<T, int64_t>) {
|
||||
JS_TRY_VAR_OR_RETURN_FALSE(cx, *result, ToBigInt64(cx, v));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (std::is_same<T, uint64_t>::value) {
|
||||
if (std::is_same_v<T, uint64_t>) {
|
||||
JS_TRY_VAR_OR_RETURN_FALSE(cx, *result, ToBigUint64(cx, v));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -839,7 +839,7 @@ wasm::ToggleProfiling(const Code& code, const CallSite& callSite, bool enabled)
|
||||
#elif defined(JS_CODEGEN_LOONGARCH64)
|
||||
uint8_t* caller = callerRetAddr - sizeof(uint32_t);
|
||||
Instruction* callerInsn = reinterpret_cast<Instruction*>(caller);
|
||||
MOZ_ASSERT(callerInsn->extractOpcode() == ((uint32_t)op_bl >> OpcodeShift));
|
||||
MOZ_ASSERT(callerInsn->extractBitField(31, 26) == ((uint32_t)op_bl >> 26));
|
||||
int32_t calleeOffset =
|
||||
int32_t(reinterpret_cast<InstJump*>(callerInsn)->extractImm26Value() << 8) >> 6;
|
||||
void* callee = caller + calleeOffset;
|
||||
|
||||
@@ -1442,6 +1442,7 @@ ReloadPrefsCallback(const char* pref, void* data)
|
||||
bool extraWarnings = Preferences::GetBool(JS_OPTIONS_DOT_STR "strict");
|
||||
|
||||
bool streams = Preferences::GetBool(JS_OPTIONS_DOT_STR "streams");
|
||||
bool weakRefs = Preferences::GetBool(JS_OPTIONS_DOT_STR "weakrefs");
|
||||
|
||||
bool unboxedObjects = Preferences::GetBool(JS_OPTIONS_DOT_STR "unboxed_objects");
|
||||
|
||||
@@ -1468,7 +1469,8 @@ ReloadPrefsCallback(const char* pref, void* data)
|
||||
.setWerror(werror)
|
||||
.setExtraWarnings(extraWarnings)
|
||||
.setArrayProtoValues(arrayProtoValues)
|
||||
.setStreams(streams);
|
||||
.setStreams(streams)
|
||||
.setWeakRefs(weakRefs);
|
||||
|
||||
JS_SetParallelParsingEnabled(cx, parallelParsing);
|
||||
JS_SetOffthreadIonCompilationEnabled(cx, offthreadIonCompilation);
|
||||
|
||||
@@ -5107,19 +5107,28 @@ nsLayoutUtils::IntrinsicForAxis(PhysicalAxis aAxis,
|
||||
styleMinBSize.GetCoordValue() == 0)) ||
|
||||
styleMaxBSize.GetUnit() != eStyleUnit_None) {
|
||||
|
||||
AspectRatio ratio = aFrame->GetIntrinsicRatio();
|
||||
AspectRatio ratio = aFrame->GetAspectRatio();
|
||||
if (ratio) {
|
||||
// Convert 'ratio' if necessary, so that it's storing ISize/BSize:
|
||||
if (!horizontalAxis) {
|
||||
ratio = ratio.Inverted();
|
||||
}
|
||||
AddStateBitToAncestors(aFrame,
|
||||
NS_FRAME_DESCENDANT_INTRINSIC_ISIZE_DEPENDS_ON_BSIZE);
|
||||
|
||||
const WritingMode wm = aFrame->GetWritingMode();
|
||||
LogicalSize boxSizingAdjust(wm);
|
||||
boxSizingAdjust.ISize(wm) =
|
||||
GetDefiniteSizeTakenByBoxSizing(boxSizing, aFrame, isInlineAxis,
|
||||
aFlags & IGNORE_PADDING,
|
||||
aPercentageBasis);
|
||||
nscoord bSizeTakenByBoxSizing =
|
||||
GetDefiniteSizeTakenByBoxSizing(boxSizing, aFrame, !isInlineAxis,
|
||||
aFlags & IGNORE_PADDING,
|
||||
aPercentageBasis);
|
||||
boxSizingAdjust.BSize(wm) = bSizeTakenByBoxSizing;
|
||||
auto iSizeFromBSize = [&](nscoord aBSize) {
|
||||
LogicalAxis dependentAxis =
|
||||
isInlineAxis ? eLogicalAxisInline : eLogicalAxisBlock;
|
||||
return ratio.ComputeRatioDependentSize(
|
||||
dependentAxis, wm, aBSize, boxSizingAdjust);
|
||||
};
|
||||
// NOTE: This is only the minContentSize if we've been passed MIN_INTRINSIC_ISIZE
|
||||
// (which is fine, because this should only be used inside a check for that flag).
|
||||
nscoord minContentSize = result;
|
||||
@@ -5128,14 +5137,14 @@ nsLayoutUtils::IntrinsicForAxis(PhysicalAxis aAxis,
|
||||
(aPercentageBasis.isNothing() &&
|
||||
GetPercentBSize(styleBSize, aFrame, horizontalAxis, h))) {
|
||||
h = std::max(0, h - bSizeTakenByBoxSizing);
|
||||
result = ratio.ApplyTo(h);
|
||||
result = iSizeFromBSize(h);
|
||||
}
|
||||
|
||||
if (GetDefiniteSize(styleMaxBSize, aFrame, !isInlineAxis, aPercentageBasis, &h) ||
|
||||
(aPercentageBasis.isNothing() &&
|
||||
GetPercentBSize(styleMaxBSize, aFrame, horizontalAxis, h))) {
|
||||
h = std::max(0, h - bSizeTakenByBoxSizing);
|
||||
nscoord maxISize = ratio.ApplyTo(h);
|
||||
nscoord maxISize = iSizeFromBSize(h);
|
||||
if (maxISize < result) {
|
||||
result = maxISize;
|
||||
}
|
||||
@@ -5148,7 +5157,7 @@ nsLayoutUtils::IntrinsicForAxis(PhysicalAxis aAxis,
|
||||
(aPercentageBasis.isNothing() &&
|
||||
GetPercentBSize(styleMinBSize, aFrame, horizontalAxis, h))) {
|
||||
h = std::max(0, h - bSizeTakenByBoxSizing);
|
||||
nscoord minISize = ratio.ApplyTo(h);
|
||||
nscoord minISize = iSizeFromBSize(h);
|
||||
if (minISize > result) {
|
||||
result = minISize;
|
||||
}
|
||||
|
||||
@@ -234,7 +234,18 @@ nsHTMLButtonControlFrame::ReflowButtonContents(nsPresContext* aPresContext,
|
||||
{
|
||||
WritingMode wm = GetWritingMode();
|
||||
LogicalSize availSize = aButtonReflowInput.ComputedSize(wm);
|
||||
availSize.BSize(wm) = NS_INTRINSICSIZE;
|
||||
|
||||
// Identify if the inner anonymous block is actually functioning as a flex or grid container.
|
||||
nsIAtom* kidType = aFirstKid->GetType();
|
||||
bool isFlexOrGrid = (kidType == nsGkAtoms::flexContainerFrame ||
|
||||
kidType == nsGkAtoms::gridContainerFrame);
|
||||
|
||||
// Preserve the button's definite BSize ONLY for flex/grid children so they
|
||||
// see a definite containing block main size. For standard buttons, clobber
|
||||
// to intrinsic so standard vertical centering (extraSpace) calculations work.
|
||||
if (!isFlexOrGrid || aButtonReflowInput.ComputedBSize() == NS_INTRINSICSIZE) {
|
||||
availSize.BSize(wm) = NS_INTRINSICSIZE;
|
||||
}
|
||||
|
||||
// shorthand for a value we need to use in a bunch of places
|
||||
const LogicalMargin& clbp = aButtonReflowInput.ComputedLogicalBorderPadding();
|
||||
@@ -248,6 +259,12 @@ nsHTMLButtonControlFrame::ReflowButtonContents(nsPresContext* aPresContext,
|
||||
aFirstKid,
|
||||
availSize);
|
||||
|
||||
// Apply the definite BSize directly on the inner reflow input ONLY if it's
|
||||
// a flex or grid container, allowing it to be used as-is.
|
||||
if (isFlexOrGrid && aButtonReflowInput.ComputedBSize() != NS_INTRINSICSIZE) {
|
||||
contentsReflowInput.SetComputedBSize(aButtonReflowInput.ComputedBSize());
|
||||
}
|
||||
|
||||
nsReflowStatus contentsReflowStatus;
|
||||
ReflowOutput contentsDesiredSize(aButtonReflowInput);
|
||||
childPos.B(wm) = 0; // This will be set properly later, after reflowing the
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/* 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/. */
|
||||
|
||||
#include "mozilla/AspectRatio.h"
|
||||
|
||||
#include "mozilla/WritingModes.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
nscoord
|
||||
AspectRatio::ComputeRatioDependentSize(
|
||||
LogicalAxis aRatioDependentAxis,
|
||||
const WritingMode& aWM,
|
||||
nscoord aRatioDeterminingSize,
|
||||
const LogicalSize& aContentBoxToBoxSizingAdjust) const
|
||||
{
|
||||
MOZ_DIAGNOSTIC_ASSERT(*this);
|
||||
|
||||
LogicalSize adjust(aWM);
|
||||
if (mUseBoxSizing == UseBoxSizing::Yes) {
|
||||
adjust = aContentBoxToBoxSizingAdjust;
|
||||
}
|
||||
|
||||
AspectRatio logicalRatio = aWM.IsVertical() ? Inverted() : *this;
|
||||
nscoord result;
|
||||
if (aRatioDependentAxis == eLogicalAxisInline) {
|
||||
result = logicalRatio.ApplyTo(aRatioDeterminingSize +
|
||||
adjust.BSize(aWM)) -
|
||||
adjust.ISize(aWM);
|
||||
} else {
|
||||
result = logicalRatio.Inverted().ApplyTo(aRatioDeterminingSize +
|
||||
adjust.ISize(aWM)) -
|
||||
adjust.BSize(aWM);
|
||||
}
|
||||
return std::max(nscoord(0), result);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
@@ -9,21 +9,46 @@
|
||||
/* The aspect ratio of a box, in a "width / height" format. */
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/LogicalTypes.h"
|
||||
#include "nsCoord.h"
|
||||
#include "nsSize.h"
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
struct AspectRatio {
|
||||
AspectRatio() : mRatio(0.0f) {}
|
||||
explicit AspectRatio(float aRatio) : mRatio(std::max(aRatio, 0.0f)) {}
|
||||
class LogicalSize;
|
||||
class WritingMode;
|
||||
|
||||
static AspectRatio FromSize(float aWidth, float aHeight) {
|
||||
enum class UseBoxSizing : uint8_t {
|
||||
// Natural ratios and "auto <ratio>" always use content-box dimensions.
|
||||
No,
|
||||
// A specified <ratio> uses the dimensions selected by box-sizing.
|
||||
Yes,
|
||||
};
|
||||
|
||||
struct AspectRatio {
|
||||
AspectRatio()
|
||||
: mRatio(0.0f)
|
||||
, mUseBoxSizing(UseBoxSizing::No)
|
||||
{}
|
||||
|
||||
explicit AspectRatio(float aRatio,
|
||||
UseBoxSizing aUseBoxSizing = UseBoxSizing::No)
|
||||
: mRatio(std::max(aRatio, 0.0f))
|
||||
, mUseBoxSizing(aUseBoxSizing)
|
||||
{}
|
||||
|
||||
static AspectRatio FromSize(float aWidth, float aHeight,
|
||||
UseBoxSizing aUseBoxSizing = UseBoxSizing::No) {
|
||||
if (aWidth == 0.0f || aHeight == 0.0f) {
|
||||
return AspectRatio();
|
||||
}
|
||||
return AspectRatio(aWidth / aHeight);
|
||||
float ratio = aWidth / aHeight;
|
||||
if (!std::isfinite(ratio)) {
|
||||
return AspectRatio();
|
||||
}
|
||||
return AspectRatio(ratio, aUseBoxSizing);
|
||||
}
|
||||
|
||||
static AspectRatio FromSize(nsSize aSize) {
|
||||
@@ -55,11 +80,23 @@ struct AspectRatio {
|
||||
// 0.0f in the division here (so that valid ratios always generate other
|
||||
// valid ratios when inverted).
|
||||
return AspectRatio(
|
||||
std::max(std::numeric_limits<float>::epsilon(), 1.0f / mRatio));
|
||||
std::max(std::numeric_limits<float>::epsilon(), 1.0f / mRatio),
|
||||
mUseBoxSizing);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes a content-box size in the ratio-dependent axis from a
|
||||
* content-box size in the ratio-determining axis.
|
||||
*/
|
||||
nscoord ComputeRatioDependentSize(
|
||||
LogicalAxis aRatioDependentAxis,
|
||||
const WritingMode& aWM,
|
||||
nscoord aRatioDeterminingSize,
|
||||
const LogicalSize& aContentBoxToBoxSizingAdjust) const;
|
||||
|
||||
bool operator==(const AspectRatio& aOther) const {
|
||||
return mRatio == aOther.mRatio;
|
||||
return mRatio == aOther.mRatio &&
|
||||
mUseBoxSizing == aOther.mUseBoxSizing;
|
||||
}
|
||||
|
||||
bool operator!=(const AspectRatio& aOther) const {
|
||||
@@ -73,6 +110,7 @@ struct AspectRatio {
|
||||
private:
|
||||
// 0.0f represents no aspect ratio.
|
||||
float mRatio;
|
||||
UseBoxSizing mUseBoxSizing;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/* -*- Mode: C++; 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/. */
|
||||
|
||||
#ifndef mozilla_LogicalTypes_h
|
||||
#define mozilla_LogicalTypes_h
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
// Logical axis, edge, side and corner constants for use in various places.
|
||||
enum LogicalAxis {
|
||||
eLogicalAxisBlock = 0x0,
|
||||
eLogicalAxisInline = 0x1
|
||||
};
|
||||
enum LogicalEdge {
|
||||
eLogicalEdgeStart = 0x0,
|
||||
eLogicalEdgeEnd = 0x1
|
||||
};
|
||||
enum LogicalSide {
|
||||
eLogicalSideBStart = (eLogicalAxisBlock << 1) | eLogicalEdgeStart, // 0x0
|
||||
eLogicalSideBEnd = (eLogicalAxisBlock << 1) | eLogicalEdgeEnd, // 0x1
|
||||
eLogicalSideIStart = (eLogicalAxisInline << 1) | eLogicalEdgeStart, // 0x2
|
||||
eLogicalSideIEnd = (eLogicalAxisInline << 1) | eLogicalEdgeEnd // 0x3
|
||||
};
|
||||
|
||||
enum LogicalCorner
|
||||
{
|
||||
eLogicalCornerBStartIStart = 0,
|
||||
eLogicalCornerBStartIEnd = 1,
|
||||
eLogicalCornerBEndIEnd = 2,
|
||||
eLogicalCornerBEndIStart = 3
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_LogicalTypes_h
|
||||
@@ -6,6 +6,7 @@
|
||||
#ifndef WritingModes_h_
|
||||
#define WritingModes_h_
|
||||
|
||||
#include "mozilla/LogicalTypes.h"
|
||||
#include "nsRect.h"
|
||||
#include "nsStyleContext.h"
|
||||
#include "nsBidiUtils.h"
|
||||
|
||||
@@ -110,6 +110,7 @@ EXPORTS += [
|
||||
EXPORTS.mozilla += [
|
||||
'AspectRatio.h',
|
||||
'CSSAlignUtils.h',
|
||||
'LogicalTypes.h',
|
||||
'ReflowInput.h',
|
||||
'ReflowOutput.h',
|
||||
'WritingModes.h',
|
||||
@@ -124,6 +125,7 @@ EXPORTS.mozilla.layout += [
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'AspectRatio.cpp',
|
||||
'AsyncScrollBase.cpp',
|
||||
'BlockReflowInput.cpp',
|
||||
'CSSAlignUtils.cpp',
|
||||
|
||||
@@ -1945,7 +1945,7 @@ FlexItem::FlexItem(ReflowInput& aFlexItemReflowInput,
|
||||
: mFrame(aFlexItemReflowInput.mFrame),
|
||||
mFlexGrow(aFlexGrow),
|
||||
mFlexShrink(aFlexShrink),
|
||||
mIntrinsicRatio(mFrame->GetIntrinsicRatio()),
|
||||
mIntrinsicRatio(mFrame->GetAspectRatio()),
|
||||
mBorderPadding(aFlexItemReflowInput.ComputedPhysicalBorderPadding()),
|
||||
mMargin(aFlexItemReflowInput.ComputedPhysicalMargin()),
|
||||
mMainMinSize(aMainMinSize),
|
||||
|
||||
+67
-26
@@ -4655,10 +4655,44 @@ nsFrame::GetIntrinsicSize()
|
||||
/* virtual */ AspectRatio
|
||||
nsFrame::GetIntrinsicRatio()
|
||||
{
|
||||
const nsStylePosition* stylePos = StylePosition();
|
||||
return stylePos->mAspectRatio == 0.0f
|
||||
? AspectRatio()
|
||||
: AspectRatio(stylePos->mAspectRatio);
|
||||
return AspectRatio();
|
||||
}
|
||||
|
||||
AspectRatio
|
||||
nsIFrame::GetAspectRatio()
|
||||
{
|
||||
// The property does not apply to inline boxes or internal ruby/table boxes.
|
||||
nsIAtom* type = GetType();
|
||||
if (type == nsGkAtoms::inlineFrame ||
|
||||
RubyUtils::IsRubyBox(type) ||
|
||||
type == nsGkAtoms::tableCellFrame ||
|
||||
type == nsGkAtoms::tableColFrame ||
|
||||
type == nsGkAtoms::tableColGroupFrame ||
|
||||
type == nsGkAtoms::tableRowFrame ||
|
||||
type == nsGkAtoms::tableRowGroupFrame) {
|
||||
return AspectRatio();
|
||||
}
|
||||
|
||||
const StyleAspectRatio& styleRatio = StylePosition()->mAspectRatio;
|
||||
|
||||
// A non-auto, non-degenerate ratio overrides the natural ratio and uses the
|
||||
// box selected by box-sizing.
|
||||
if (!styleRatio.mAuto && styleRatio.HasUsableRatio()) {
|
||||
return AspectRatio::FromSize(styleRatio.mWidth, styleRatio.mHeight,
|
||||
UseBoxSizing::Yes);
|
||||
}
|
||||
|
||||
if (AspectRatio intrinsicRatio = GetIntrinsicRatio()) {
|
||||
return intrinsicRatio;
|
||||
}
|
||||
|
||||
// The fallback in "auto <ratio>" always operates on the content box.
|
||||
if (styleRatio.HasUsableRatio()) {
|
||||
return AspectRatio::FromSize(styleRatio.mWidth, styleRatio.mHeight,
|
||||
UseBoxSizing::No);
|
||||
}
|
||||
|
||||
return AspectRatio();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -4727,11 +4761,11 @@ nsFrame::ComputeSize(nsRenderingContext* aRenderingContext,
|
||||
const LogicalSize& aPadding,
|
||||
ComputeSizeFlags aFlags)
|
||||
{
|
||||
AspectRatio intrinsicRatio = GetIntrinsicRatio();
|
||||
if (intrinsicRatio) {
|
||||
AspectRatio aspectRatio = GetAspectRatio();
|
||||
if (aspectRatio) {
|
||||
return ComputeSizeWithIntrinsicDimensions(aRenderingContext, aWM,
|
||||
GetIntrinsicSize(),
|
||||
intrinsicRatio,
|
||||
aspectRatio,
|
||||
aCBSize, aMargin,
|
||||
aBorder, aPadding,
|
||||
aFlags);
|
||||
@@ -4976,8 +5010,6 @@ nsFrame::ComputeSizeWithIntrinsicDimensions(nsRenderingContext* aRenderingConte
|
||||
const LogicalSize& aPadding,
|
||||
ComputeSizeFlags aFlags)
|
||||
{
|
||||
auto logicalRatio =
|
||||
aWM.IsVertical() ? aIntrinsicRatio.Inverted() : aIntrinsicRatio;
|
||||
const nsStylePosition* stylePos = StylePosition();
|
||||
const nsStyleCoord* inlineStyleCoord = &stylePos->ISize(aWM);
|
||||
const nsStyleCoord* blockStyleCoord = &stylePos->BSize(aWM);
|
||||
@@ -5039,6 +5071,14 @@ nsFrame::ComputeSizeWithIntrinsicDimensions(nsRenderingContext* aRenderingConte
|
||||
if (stylePos->mBoxSizing == StyleBoxSizing::Border) {
|
||||
boxSizingAdjust = aBorder + aPadding;
|
||||
}
|
||||
auto iSizeFromBSize = [&](nscoord aBSize) {
|
||||
return aIntrinsicRatio.ComputeRatioDependentSize(
|
||||
eLogicalAxisInline, aWM, aBSize, boxSizingAdjust);
|
||||
};
|
||||
auto bSizeFromISize = [&](nscoord aISize) {
|
||||
return aIntrinsicRatio.ComputeRatioDependentSize(
|
||||
eLogicalAxisBlock, aWM, aISize, boxSizingAdjust);
|
||||
};
|
||||
nscoord boxSizingToMarginEdgeISize =
|
||||
aMargin.ISize(aWM) + aBorder.ISize(aWM) + aPadding.ISize(aWM) -
|
||||
boxSizingAdjust.ISize(aWM);
|
||||
@@ -5129,7 +5169,8 @@ nsFrame::ComputeSizeWithIntrinsicDimensions(nsRenderingContext* aRenderingConte
|
||||
bSize = nsLayoutUtils::ComputeBSizeValue(aCBSize.BSize(aWM),
|
||||
boxSizingAdjust.BSize(aWM),
|
||||
*blockStyleCoord);
|
||||
} else if (MOZ_UNLIKELY(isGridItem)) {
|
||||
} else if (MOZ_UNLIKELY(isGridItem) &&
|
||||
!(aFlags & nsIFrame::eUseAutoBSize)) {
|
||||
MOZ_ASSERT(!IS_TRUE_OVERFLOW_CONTAINER(this));
|
||||
// 'auto' block-size for grid-level box - apply 'stretch' as needed:
|
||||
auto cbSize = aCBSize.BSize(aWM);
|
||||
@@ -5230,9 +5271,9 @@ nsFrame::ComputeSizeWithIntrinsicDimensions(nsRenderingContext* aRenderingConte
|
||||
|
||||
if (hasIntrinsicISize) {
|
||||
tentISize = intrinsicISize;
|
||||
} else if (hasIntrinsicBSize && logicalRatio) {
|
||||
tentISize = logicalRatio.ApplyTo(intrinsicBSize);
|
||||
} else if (logicalRatio) {
|
||||
} else if (hasIntrinsicBSize && aIntrinsicRatio) {
|
||||
tentISize = iSizeFromBSize(intrinsicBSize);
|
||||
} else if (aIntrinsicRatio) {
|
||||
tentISize = aCBSize.ISize(aWM) - boxSizingToMarginEdgeISize; // XXX scrollbar?
|
||||
if (tentISize < 0) tentISize = 0;
|
||||
} else {
|
||||
@@ -5249,8 +5290,8 @@ nsFrame::ComputeSizeWithIntrinsicDimensions(nsRenderingContext* aRenderingConte
|
||||
|
||||
if (hasIntrinsicBSize) {
|
||||
tentBSize = intrinsicBSize;
|
||||
} else if (logicalRatio) {
|
||||
tentBSize = logicalRatio.Inverted().ApplyTo(tentISize);
|
||||
} else if (aIntrinsicRatio) {
|
||||
tentBSize = bSizeFromISize(tentISize);
|
||||
} else {
|
||||
tentBSize = nsPresContext::CSSPixelsToAppUnits(150);
|
||||
}
|
||||
@@ -5261,39 +5302,39 @@ nsFrame::ComputeSizeWithIntrinsicDimensions(nsRenderingContext* aRenderingConte
|
||||
stretchB = (stretchI == eStretch ? eStretch : eStretchPreservingRatio);
|
||||
}
|
||||
|
||||
if (logicalRatio) {
|
||||
if (aIntrinsicRatio) {
|
||||
if (stretchI == eStretch) {
|
||||
tentISize = iSize; // * / 'stretch'
|
||||
if (stretchB == eStretch) {
|
||||
tentBSize = bSize; // 'stretch' / 'stretch'
|
||||
} else if (stretchB == eStretchPreservingRatio) {
|
||||
// 'normal' / 'stretch'
|
||||
tentBSize = logicalRatio.Inverted().ApplyTo(iSize);
|
||||
tentBSize = bSizeFromISize(iSize);
|
||||
}
|
||||
} else if (stretchB == eStretch) {
|
||||
tentBSize = bSize; // 'stretch' / * (except 'stretch')
|
||||
if (stretchI == eStretchPreservingRatio) {
|
||||
// 'stretch' / 'normal'
|
||||
tentISize = logicalRatio.ApplyTo(bSize);
|
||||
tentISize = iSizeFromBSize(bSize);
|
||||
}
|
||||
} else if (stretchI == eStretchPreservingRatio) {
|
||||
tentISize = iSize; // * (except 'stretch') / 'normal'
|
||||
tentBSize = logicalRatio.Inverted().ApplyTo(iSize);
|
||||
tentBSize = bSizeFromISize(iSize);
|
||||
if (stretchB == eStretchPreservingRatio && tentBSize > bSize) {
|
||||
// Stretch within the CB size with preserved intrinsic ratio.
|
||||
tentBSize = bSize; // 'normal' / 'normal'
|
||||
tentISize = logicalRatio.ApplyTo(bSize);
|
||||
tentISize = iSizeFromBSize(bSize);
|
||||
}
|
||||
} else if (stretchB == eStretchPreservingRatio) {
|
||||
tentBSize = bSize; // 'normal' / * (except 'normal' and 'stretch')
|
||||
tentISize = logicalRatio.ApplyTo(bSize);
|
||||
tentISize = iSizeFromBSize(bSize);
|
||||
}
|
||||
}
|
||||
|
||||
// ComputeAutoSizeWithIntrinsicDimensions preserves the ratio when applying
|
||||
// the min/max-size. We don't want that when we have 'stretch' in either
|
||||
// axis because tentISize/tentBSize is likely not according to ratio now.
|
||||
if (logicalRatio && stretchI != eStretch && stretchB != eStretch) {
|
||||
if (aIntrinsicRatio && stretchI != eStretch && stretchB != eStretch) {
|
||||
nsSize autoSize = nsLayoutUtils::
|
||||
ComputeAutoSizeWithIntrinsicDimensions(minISize, minBSize,
|
||||
maxISize, maxBSize,
|
||||
@@ -5314,8 +5355,8 @@ nsFrame::ComputeSizeWithIntrinsicDimensions(nsRenderingContext* aRenderingConte
|
||||
// 'auto' iSize, non-'auto' bSize
|
||||
bSize = NS_CSS_MINMAX(bSize, minBSize, maxBSize);
|
||||
if (stretchI != eStretch) {
|
||||
if (logicalRatio) {
|
||||
iSize = logicalRatio.ApplyTo(bSize);
|
||||
if (aIntrinsicRatio) {
|
||||
iSize = iSizeFromBSize(bSize);
|
||||
} else if (hasIntrinsicISize) {
|
||||
if (!((aFlags & ComputeSizeFlags::eIClampMarginBoxMinSize) &&
|
||||
intrinsicISize > iSize)) {
|
||||
@@ -5334,8 +5375,8 @@ nsFrame::ComputeSizeWithIntrinsicDimensions(nsRenderingContext* aRenderingConte
|
||||
// non-'auto' iSize, 'auto' bSize
|
||||
iSize = NS_CSS_MINMAX(iSize, minISize, maxISize);
|
||||
if (stretchB != eStretch) {
|
||||
if (logicalRatio) {
|
||||
bSize = logicalRatio.Inverted().ApplyTo(iSize);
|
||||
if (aIntrinsicRatio) {
|
||||
bSize = bSizeFromISize(iSize);
|
||||
} else if (hasIntrinsicBSize) {
|
||||
if (!((aFlags & ComputeSizeFlags::eBClampMarginBoxMinSize) &&
|
||||
intrinsicBSize > bSize)) {
|
||||
|
||||
@@ -225,7 +225,7 @@ nsHTMLCanvasFrame::ComputeSize(nsRenderingContext *aRenderingContext,
|
||||
intrinsicSize.width.SetCoordValue(nsPresContext::CSSPixelsToAppUnits(size.width));
|
||||
intrinsicSize.height.SetCoordValue(nsPresContext::CSSPixelsToAppUnits(size.height));
|
||||
|
||||
AspectRatio intrinsicRatio = GetIntrinsicRatio();
|
||||
AspectRatio intrinsicRatio = GetAspectRatio();
|
||||
|
||||
return ComputeSizeWithIntrinsicDimensions(aRenderingContext, aWM,
|
||||
intrinsicSize, intrinsicRatio,
|
||||
@@ -424,4 +424,3 @@ nsHTMLCanvasFrame::GetFrameName(nsAString& aResult) const
|
||||
return MakeFrameName(NS_LITERAL_STRING("HTMLCanvas"), aResult);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2078,6 +2078,12 @@ public:
|
||||
|
||||
virtual mozilla::IntrinsicSize GetIntrinsicSize() = 0;
|
||||
|
||||
/**
|
||||
* Get the preferred aspect ratio after applying the aspect-ratio property
|
||||
* to this frame's natural ratio.
|
||||
*/
|
||||
mozilla::AspectRatio GetAspectRatio();
|
||||
|
||||
/**
|
||||
* Get the intrinsic ratio of this element, or a default-constructed
|
||||
* AspectRatio if it has no intrinsic ratio.
|
||||
|
||||
@@ -320,7 +320,7 @@ ComputeIntrinsicSize(imgIContainer* aImage,
|
||||
}
|
||||
*/
|
||||
|
||||
if (aUseMappedRatio && aFrame.StylePosition()->mAspectRatio != 0.0f) {
|
||||
if (aUseMappedRatio && aFrame.StylePosition()->mAspectRatio.HasRatio()) {
|
||||
return IntrinsicSize();
|
||||
}
|
||||
|
||||
@@ -375,8 +375,10 @@ ComputeAspectRatio(imgIContainer* aImage,
|
||||
return fromImage;
|
||||
}
|
||||
}
|
||||
if (aUseMappedRatio && aFrame.StylePosition()->mAspectRatio != 0.0f) {
|
||||
return AspectRatio(aFrame.StylePosition()->mAspectRatio);
|
||||
if (aUseMappedRatio &&
|
||||
aFrame.StylePosition()->mAspectRatio.HasUsableRatio()) {
|
||||
const StyleAspectRatio& ratio = aFrame.StylePosition()->mAspectRatio;
|
||||
return AspectRatio::FromSize(ratio.mWidth, ratio.mHeight);
|
||||
}
|
||||
if (aFrame.ShouldShowBrokenImageIcon()) {
|
||||
return AspectRatio(1.0f);
|
||||
@@ -891,7 +893,7 @@ nsImageFrame::ComputeSize(nsRenderingContext *aRenderingContext,
|
||||
}
|
||||
|
||||
return ComputeSizeWithIntrinsicDimensions(aRenderingContext, aWM,
|
||||
intrinsicSize, mIntrinsicRatio,
|
||||
intrinsicSize, GetAspectRatio(),
|
||||
aCBSize, aMargin, aBorder, aPadding,
|
||||
aFlags);
|
||||
}
|
||||
|
||||
@@ -786,7 +786,7 @@ IsPercentageAware(const nsIFrame* aFrame)
|
||||
// is calculated from the constraint equation used for
|
||||
// block-level, non-replaced elements in normal flow.
|
||||
nsIFrame *f = const_cast<nsIFrame*>(aFrame);
|
||||
if (f->GetIntrinsicRatio() &&
|
||||
if (f->GetAspectRatio() &&
|
||||
// Some percents are treated like 'auto', so check != coord
|
||||
pos->mHeight.GetUnit() != eStyleUnit_Coord) {
|
||||
const IntrinsicSize &intrinsicSize = f->GetIntrinsicSize();
|
||||
|
||||
@@ -721,7 +721,7 @@ nsSubDocumentFrame::ComputeSize(nsRenderingContext* aRenderingContext,
|
||||
if (subDocRoot) {
|
||||
return ComputeSizeWithIntrinsicDimensions(aRenderingContext, aWM,
|
||||
subDocRoot->GetIntrinsicSize(),
|
||||
subDocRoot->GetIntrinsicRatio(),
|
||||
GetAspectRatio(),
|
||||
aCBSize, aMargin, aBorder,
|
||||
aPadding, aFlags);
|
||||
}
|
||||
|
||||
@@ -318,7 +318,7 @@ nsCaseTransformTextRunFactory::TransformString(
|
||||
// in the output string
|
||||
uint32_t irishMarkSrc = uint32_t(-1); // corresponding location in source
|
||||
// string (may differ from output due to
|
||||
// expansions like eszet -> 'SS')
|
||||
// expansions)
|
||||
|
||||
for (uint32_t i = 0; i < length; ++i, ++aOffsetInTextRun) {
|
||||
uint32_t ch = str[i];
|
||||
@@ -604,6 +604,13 @@ nsCaseTransformTextRunFactory::TransformString(
|
||||
// to check for special uppercase (ß)
|
||||
}
|
||||
|
||||
// Updated mapping for Germen eszett, not currently reflected in the
|
||||
// Unicode data files.
|
||||
if (ch == 0x00DF) {
|
||||
ch = 0x1E9E;
|
||||
break;
|
||||
}
|
||||
|
||||
mcm = mozilla::unicode::SpecialUpper(ch);
|
||||
if (mcm) {
|
||||
int j = 0;
|
||||
@@ -658,6 +665,12 @@ nsCaseTransformTextRunFactory::TransformString(
|
||||
}
|
||||
}
|
||||
|
||||
// Updated mapping for Germen eszett as a capital letter.
|
||||
if (ch == 0x00DF) {
|
||||
ch = 0x1E9E;
|
||||
break;
|
||||
}
|
||||
|
||||
mcm = mozilla::unicode::SpecialTitle(ch);
|
||||
if (mcm) {
|
||||
int j = 0;
|
||||
|
||||
@@ -543,13 +543,8 @@ nsVideoFrame::ComputeSize(nsRenderingContext *aRenderingContext,
|
||||
intrinsicSize.width.SetCoordValue(size.width);
|
||||
intrinsicSize.height.SetCoordValue(size.height);
|
||||
|
||||
// Only video elements have an intrinsic ratio.
|
||||
auto intrinsicRatio = HasVideoElement() ?
|
||||
AspectRatio::FromSize(size) :
|
||||
AspectRatio();
|
||||
|
||||
return ComputeSizeWithIntrinsicDimensions(aRenderingContext, aWM,
|
||||
intrinsicSize, intrinsicRatio,
|
||||
intrinsicSize, GetAspectRatio(),
|
||||
aCBSize, aMargin, aBorder, aPadding,
|
||||
aFlags);
|
||||
}
|
||||
|
||||
@@ -953,11 +953,12 @@ inDOMUtils::GetCSSValuesForProperty(const nsAString& aProperty,
|
||||
GetOtherValuesForProperty(propertyParserVariant, array);
|
||||
}
|
||||
}
|
||||
// All CSS properties take initial, inherit, unset, and revert.
|
||||
// All CSS properties take initial, inherit, unset, revert, and revert-layer.
|
||||
InsertNoDuplicates(array, NS_LITERAL_STRING("initial"));
|
||||
InsertNoDuplicates(array, NS_LITERAL_STRING("inherit"));
|
||||
InsertNoDuplicates(array, NS_LITERAL_STRING("unset"));
|
||||
InsertNoDuplicates(array, NS_LITERAL_STRING("revert"));
|
||||
InsertNoDuplicates(array, NS_LITERAL_STRING("revert-layer"));
|
||||
|
||||
*aLength = array.Length();
|
||||
char16_t** ret =
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Grid: aspect-ratio contributes to an auto row reference</title>
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.gallery {
|
||||
display: grid;
|
||||
width: 640px;
|
||||
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
||||
gap: 20px;
|
||||
padding: 30px;
|
||||
}
|
||||
.item {
|
||||
position: relative;
|
||||
height: 280px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.item > div {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: green;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="gallery">
|
||||
<div class="item"><div></div></div>
|
||||
<div class="item"><div></div></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,39 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Grid: aspect-ratio contributes to an auto row</title>
|
||||
<link rel="match" href="grid-item-aspect-ratio-001-ref.html">
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.gallery {
|
||||
display: grid;
|
||||
width: 640px;
|
||||
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
||||
gap: 20px;
|
||||
padding: 30px;
|
||||
}
|
||||
.item {
|
||||
position: relative;
|
||||
aspect-ratio: 1;
|
||||
overflow: hidden;
|
||||
background: red;
|
||||
}
|
||||
.item > div {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: green;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="gallery">
|
||||
<div class="item"><div></div></div>
|
||||
<div class="item"><div></div></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -280,5 +280,6 @@ asserts(0-10) == grid-fragmentation-015.html grid-fragmentation-015-ref.html # b
|
||||
== grid-fragmentation-dyn2-031.html grid-fragmentation-031-ref.html
|
||||
== bug1306106.html bug1306106-ref.html
|
||||
== grid-percent-intrinsic-sizing-001.html grid-percent-intrinsic-sizing-001-ref.html
|
||||
== grid-item-aspect-ratio-001.html grid-item-aspect-ratio-001-ref.html
|
||||
== bug1349571.html bug1349571-ref.html
|
||||
== bug1356820.html bug1356820-ref.html
|
||||
@@ -1987,6 +1987,86 @@ CSSStyleSheet::DeleteRuleInternal(uint32_t aIndex, ErrorResult& aRv)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CSSStyleSheet::ReplaceSyncInternal(const nsAString& aText, ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(mInner->mComplete);
|
||||
|
||||
RefPtr<CSSStyleSheet> parsedSheet =
|
||||
new CSSStyleSheet(mParsingMode, GetCORSMode(), GetReferrerPolicy());
|
||||
parsedSheet->SetURIs(mInner->mSheetURI, mInner->mOriginalSheetURI,
|
||||
mInner->mBaseURI);
|
||||
parsedSheet->SetPrincipal(mInner->mPrincipal);
|
||||
parsedSheet->SetComplete();
|
||||
|
||||
nsCSSParser parser(nullptr, parsedSheet);
|
||||
nsresult rv = parser.ParseSheet(aText, parsedSheet->GetSheetURI(),
|
||||
parsedSheet->GetBaseURI(),
|
||||
parsedSheet->Principal(), 1);
|
||||
if (NS_FAILED(rv)) {
|
||||
parsedSheet->mInner->mOrderedRules.EnumerateForwards(SetStyleSheetReference,
|
||||
nullptr);
|
||||
parsedSheet->mInner->mOrderedRules.Clear();
|
||||
}
|
||||
|
||||
for (int32_t index = parsedSheet->mInner->mOrderedRules.Count() - 1;
|
||||
index >= 0; --index) {
|
||||
RefPtr<css::Rule> rule = parsedSheet->mInner->mOrderedRules.ObjectAt(index);
|
||||
if (rule->GetType() == css::Rule::IMPORT_RULE) {
|
||||
parsedSheet->mInner->mOrderedRules.RemoveObjectAt(index);
|
||||
rule->SetStyleSheet(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
mozAutoDocUpdate updateBatch(mDocument, UPDATE_STYLE, true);
|
||||
|
||||
WillDirty();
|
||||
|
||||
while (mInner->mOrderedRules.Count() != 0) {
|
||||
RefPtr<css::Rule> rule =
|
||||
mInner->mOrderedRules.ObjectAt(mInner->mOrderedRules.Count() - 1);
|
||||
mInner->mOrderedRules.RemoveObjectAt(mInner->mOrderedRules.Count() - 1);
|
||||
rule->SetStyleSheet(nullptr);
|
||||
if (mDocument) {
|
||||
mDocument->StyleRuleRemoved(this, rule);
|
||||
}
|
||||
}
|
||||
|
||||
for (CSSStyleSheet* child = mInner->mFirstChild; child; ) {
|
||||
NS_ASSERTION(child->mParent == this, "Child sheet is not parented to this!");
|
||||
CSSStyleSheet* next = child->mNext;
|
||||
child->mParent = nullptr;
|
||||
child->mDocument = nullptr;
|
||||
child->mNext = nullptr;
|
||||
child = next;
|
||||
}
|
||||
mInner->mFirstChild = nullptr;
|
||||
mInner->mNameSpaceMap = nullptr;
|
||||
|
||||
for (int32_t index = 0; index < parsedSheet->mInner->mOrderedRules.Count();
|
||||
++index) {
|
||||
RefPtr<css::Rule> rule = parsedSheet->mInner->mOrderedRules.ObjectAt(index);
|
||||
if (!mInner->mOrderedRules.AppendObject(rule)) {
|
||||
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
rule->SetStyleSheet(this);
|
||||
}
|
||||
parsedSheet->mInner->mOrderedRules.Clear();
|
||||
parsedSheet->mInner->mNameSpaceMap = nullptr;
|
||||
|
||||
mInner->RebuildNameSpaces();
|
||||
|
||||
DidDirty();
|
||||
|
||||
if (mDocument) {
|
||||
for (int32_t index = 0; index < mInner->mOrderedRules.Count(); ++index) {
|
||||
RefPtr<css::Rule> rule = mInner->mOrderedRules.ObjectAt(index);
|
||||
mDocument->StyleRuleAdded(this, rule);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
CSSStyleSheet::DeleteRuleFromGroup(css::GroupRule* aGroup, uint32_t aIndex)
|
||||
{
|
||||
|
||||
@@ -253,6 +253,7 @@ protected:
|
||||
uint32_t InsertRuleInternal(const nsAString& aRule,
|
||||
uint32_t aIndex, ErrorResult& aRv);
|
||||
void DeleteRuleInternal(uint32_t aIndex, ErrorResult& aRv);
|
||||
void ReplaceSyncInternal(const nsAString& aText, ErrorResult& aRv);
|
||||
|
||||
RefPtr<nsMediaList> mMedia;
|
||||
RefPtr<CSSStyleSheet> mNext;
|
||||
|
||||
@@ -8,19 +8,227 @@
|
||||
#include "CSSVariableDeclarations.h"
|
||||
|
||||
#include "CSSVariableResolver.h"
|
||||
#include "CSSVariableValues.h"
|
||||
#include "nsCSSScanner.h"
|
||||
#include "nsRuleData.h"
|
||||
|
||||
// These four special string values are used to represent specified values of
|
||||
// 'initial', 'inherit', 'unset', and 'revert'. (Note that none of these are
|
||||
// valid variable values.)
|
||||
// These special string values are used to represent specified values of
|
||||
// CSS-wide keywords. (Note that none of these are valid variable values.)
|
||||
#define INITIAL_VALUE "!"
|
||||
#define INHERIT_VALUE ";"
|
||||
#define UNSET_VALUE ")"
|
||||
#define REVERT_VALUE ">"
|
||||
#define REVERT_LAYER_VALUE "]"
|
||||
|
||||
static const int32_t kRevertLayerMask = 0x000fffff;
|
||||
static const int32_t kRevertLayerImportant = 0x00100000;
|
||||
static const int32_t kRevertLayerOriginShift = 21;
|
||||
static const int32_t kLayerIndexMax = 0x000fffff;
|
||||
static const int32_t kCascadeRankStride = kLayerIndexMax + 1;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
static bool
|
||||
IsRevertLayerValue(const nsString& aValue)
|
||||
{
|
||||
return StringBeginsWith(aValue, NS_LITERAL_STRING(REVERT_LAYER_VALUE));
|
||||
}
|
||||
|
||||
static bool
|
||||
ValueMightResolveToRevertLayer(const nsString& aValue)
|
||||
{
|
||||
return IsRevertLayerValue(aValue) ||
|
||||
aValue.Find(NS_LITERAL_STRING("revert-layer")) != kNotFound;
|
||||
}
|
||||
|
||||
static int32_t
|
||||
PackRevertLayerData(SheetType aLevel, bool aIsImportant,
|
||||
int32_t aLayerIndex)
|
||||
{
|
||||
MOZ_ASSERT(aLayerIndex >= 0 && aLayerIndex <= kRevertLayerMask);
|
||||
return (uint32_t(aLevel) << kRevertLayerOriginShift) |
|
||||
(aIsImportant ? kRevertLayerImportant : 0) |
|
||||
(aLayerIndex & kRevertLayerMask);
|
||||
}
|
||||
|
||||
static void
|
||||
SetRevertLayerData(nsString& aValue, const nsRuleData* aRuleData)
|
||||
{
|
||||
aValue.AssignLiteral(REVERT_LAYER_VALUE);
|
||||
aValue.AppendInt(PackRevertLayerData(aRuleData->mLevel,
|
||||
aRuleData->mIsImportantRule,
|
||||
aRuleData->mLayerIndex));
|
||||
}
|
||||
|
||||
static bool
|
||||
UnpackRevertLayerData(const nsString& aValue, SheetType& aLevel,
|
||||
bool& aIsImportant, int32_t& aLayerIndex)
|
||||
{
|
||||
if (!IsRevertLayerValue(aValue) ||
|
||||
aValue.Length() == NS_LITERAL_STRING(REVERT_LAYER_VALUE).Length()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
nsAutoString metadata;
|
||||
metadata.Assign(Substring(aValue,
|
||||
NS_LITERAL_STRING(REVERT_LAYER_VALUE).Length()));
|
||||
int32_t packed = metadata.ToInteger(&rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aLevel = SheetType(uint32_t(packed) >> kRevertLayerOriginShift);
|
||||
aIsImportant = (packed & kRevertLayerImportant) != 0;
|
||||
aLayerIndex = packed & kRevertLayerMask;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int32_t
|
||||
LayerIndexRank(bool aIsImportant, int32_t aLayerIndex)
|
||||
{
|
||||
MOZ_ASSERT(aLayerIndex >= 0);
|
||||
MOZ_ASSERT(aLayerIndex <= kLayerIndexMax);
|
||||
return aIsImportant ? kLayerIndexMax - aLayerIndex : aLayerIndex;
|
||||
}
|
||||
|
||||
static int32_t
|
||||
CascadePrecedenceRank(SheetType aLevel, bool aIsImportant,
|
||||
int32_t aLayerIndex)
|
||||
{
|
||||
int32_t bucket = 0;
|
||||
bool isLayeredOrigin = false;
|
||||
|
||||
switch (aLevel) {
|
||||
case SheetType::Agent:
|
||||
bucket = aIsImportant ? 14 : 0;
|
||||
isLayeredOrigin = true;
|
||||
break;
|
||||
case SheetType::User:
|
||||
bucket = aIsImportant ? 13 : 1;
|
||||
isLayeredOrigin = true;
|
||||
break;
|
||||
case SheetType::PresHint:
|
||||
bucket = 2;
|
||||
break;
|
||||
case SheetType::SVGAttrAnimation:
|
||||
bucket = 3;
|
||||
break;
|
||||
case SheetType::Doc:
|
||||
bucket = aIsImportant ? 10 : 4;
|
||||
isLayeredOrigin = true;
|
||||
break;
|
||||
case SheetType::ScopedDoc:
|
||||
bucket = aIsImportant ? 9 : 5;
|
||||
isLayeredOrigin = true;
|
||||
break;
|
||||
case SheetType::StyleAttr:
|
||||
bucket = aIsImportant ? 11 : 6;
|
||||
break;
|
||||
case SheetType::Override:
|
||||
bucket = aIsImportant ? 12 : 7;
|
||||
break;
|
||||
case SheetType::Animation:
|
||||
bucket = 8;
|
||||
break;
|
||||
case SheetType::Transition:
|
||||
bucket = 15;
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("unexpected cascade level");
|
||||
break;
|
||||
}
|
||||
|
||||
return bucket * kCascadeRankStride +
|
||||
(isLayeredOrigin ? LayerIndexRank(aIsImportant, aLayerIndex) : 0);
|
||||
}
|
||||
|
||||
static bool
|
||||
ShouldIgnoreForRevertLayerData(SheetType aSourceLevel,
|
||||
bool aSourceImportant,
|
||||
int32_t aSourceLayerIndex,
|
||||
SheetType aCandidateLevel,
|
||||
bool aCandidateImportant,
|
||||
int32_t aCandidateLayerIndex)
|
||||
{
|
||||
int32_t candidateRank =
|
||||
CascadePrecedenceRank(aCandidateLevel, aCandidateImportant,
|
||||
aCandidateLayerIndex);
|
||||
int32_t sourceRank =
|
||||
CascadePrecedenceRank(aSourceLevel, aSourceImportant, aSourceLayerIndex);
|
||||
|
||||
if (candidateRank >= sourceRank) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!aSourceImportant) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aSourceLevel == SheetType::StyleAttr) {
|
||||
return aCandidateLevel == SheetType::StyleAttr ||
|
||||
aCandidateLevel == SheetType::Animation;
|
||||
}
|
||||
|
||||
int32_t normalBoundary =
|
||||
CascadePrecedenceRank(aSourceLevel, false, aSourceLayerIndex);
|
||||
return candidateRank >= normalBoundary;
|
||||
}
|
||||
|
||||
static bool
|
||||
ShouldIgnoreForRevertLayerValue(const nsString& aTargetValue,
|
||||
SheetType aCandidateLevel,
|
||||
bool aCandidateImportant,
|
||||
int32_t aCandidateLayerIndex)
|
||||
{
|
||||
SheetType sourceLevel;
|
||||
bool sourceImportant;
|
||||
int32_t sourceLayerIndex;
|
||||
if (!UnpackRevertLayerData(aTargetValue, sourceLevel, sourceImportant,
|
||||
sourceLayerIndex)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ShouldIgnoreForRevertLayerData(sourceLevel, sourceImportant,
|
||||
sourceLayerIndex, aCandidateLevel,
|
||||
aCandidateImportant,
|
||||
aCandidateLayerIndex);
|
||||
}
|
||||
|
||||
static bool
|
||||
ShouldIgnoreForRevertLayerValue(const nsString& aTargetValue,
|
||||
const nsRuleData* aRuleData)
|
||||
{
|
||||
return ShouldIgnoreForRevertLayerValue(aTargetValue, aRuleData->mLevel,
|
||||
aRuleData->mIsImportantRule,
|
||||
aRuleData->mLayerIndex);
|
||||
}
|
||||
|
||||
static bool
|
||||
ShouldIgnoreForRevertLayerSourceValue(const nsString& aTargetValue,
|
||||
const nsString& aCandidateValue)
|
||||
{
|
||||
SheetType candidateLevel;
|
||||
bool candidateImportant;
|
||||
int32_t candidateLayerIndex;
|
||||
if (!UnpackRevertLayerData(aCandidateValue, candidateLevel,
|
||||
candidateImportant, candidateLayerIndex)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ShouldIgnoreForRevertLayerValue(aTargetValue, candidateLevel,
|
||||
candidateImportant,
|
||||
candidateLayerIndex);
|
||||
}
|
||||
|
||||
static bool
|
||||
IsComputedRevertLayerValue(const nsString& aValue)
|
||||
{
|
||||
nsAutoString trimmed(aValue);
|
||||
trimmed.CompressWhitespace(true, true);
|
||||
return trimmed.EqualsLiteral("revert-layer");
|
||||
}
|
||||
|
||||
CSSVariableDeclarations::CSSVariableDeclarations()
|
||||
{
|
||||
MOZ_COUNT_CTOR(CSSVariableDeclarations);
|
||||
@@ -47,6 +255,8 @@ CSSVariableDeclarations::operator=(const CSSVariableDeclarations& aOther)
|
||||
}
|
||||
|
||||
mVariables.Clear();
|
||||
mRevertLayerSources.Clear();
|
||||
mRevertLayerFallbacks.Clear();
|
||||
CopyVariablesFrom(aOther);
|
||||
return *this;
|
||||
}
|
||||
@@ -57,6 +267,15 @@ CSSVariableDeclarations::CopyVariablesFrom(const CSSVariableDeclarations& aOther
|
||||
for (auto iter = aOther.mVariables.ConstIter(); !iter.Done(); iter.Next()) {
|
||||
mVariables.Put(iter.Key(), iter.UserData());
|
||||
}
|
||||
for (auto iter = aOther.mRevertLayerSources.ConstIter();
|
||||
!iter.Done(); iter.Next()) {
|
||||
mRevertLayerSources.Put(iter.Key(), iter.UserData());
|
||||
}
|
||||
for (auto iter = aOther.mRevertLayerFallbacks.ConstIter();
|
||||
!iter.Done(); iter.Next()) {
|
||||
RevertLayerFallbackList* list = mRevertLayerFallbacks.LookupOrAdd(iter.Key());
|
||||
list->mItems = iter.UserData()->mItems;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -87,6 +306,9 @@ CSSVariableDeclarations::Get(const nsAString& aName,
|
||||
} else if (value.EqualsLiteral(REVERT_VALUE)) {
|
||||
aType = eRevert;
|
||||
aTokenStream.Truncate();
|
||||
} else if (IsRevertLayerValue(value)) {
|
||||
aType = eRevertLayer;
|
||||
aTokenStream.Truncate();
|
||||
} else {
|
||||
aType = eTokenStream;
|
||||
aTokenStream = value;
|
||||
@@ -101,7 +323,8 @@ CSSVariableDeclarations::PutTokenStream(const nsAString& aName,
|
||||
MOZ_ASSERT(!aTokenStream.EqualsLiteral(INITIAL_VALUE) &&
|
||||
!aTokenStream.EqualsLiteral(INHERIT_VALUE) &&
|
||||
!aTokenStream.EqualsLiteral(UNSET_VALUE) &&
|
||||
!aTokenStream.EqualsLiteral(REVERT_VALUE));
|
||||
!aTokenStream.EqualsLiteral(REVERT_VALUE) &&
|
||||
!aTokenStream.EqualsLiteral(REVERT_LAYER_VALUE));
|
||||
mVariables.Put(aName, aTokenStream);
|
||||
}
|
||||
|
||||
@@ -129,6 +352,12 @@ CSSVariableDeclarations::PutRevert(const nsAString& aName)
|
||||
mVariables.Put(aName, NS_LITERAL_STRING(REVERT_VALUE));
|
||||
}
|
||||
|
||||
void
|
||||
CSSVariableDeclarations::PutRevertLayer(const nsAString& aName)
|
||||
{
|
||||
mVariables.Put(aName, NS_LITERAL_STRING(REVERT_LAYER_VALUE));
|
||||
}
|
||||
|
||||
void
|
||||
CSSVariableDeclarations::Remove(const nsAString& aName)
|
||||
{
|
||||
@@ -143,16 +372,49 @@ CSSVariableDeclarations::MapRuleInfoInto(nsRuleData* aRuleData)
|
||||
}
|
||||
|
||||
if (!aRuleData->mVariables) {
|
||||
aRuleData->mVariables = new CSSVariableDeclarations(*this);
|
||||
} else {
|
||||
for (auto iter = mVariables.Iter(); !iter.Done(); iter.Next()) {
|
||||
nsDataHashtable<nsStringHashKey, nsString>& variables =
|
||||
aRuleData->mVariables->mVariables;
|
||||
const nsAString& aName = iter.Key();
|
||||
if (!variables.Contains(aName)) {
|
||||
variables.Put(aName, iter.UserData());
|
||||
aRuleData->mVariables = new CSSVariableDeclarations;
|
||||
}
|
||||
|
||||
for (auto iter = mVariables.Iter(); !iter.Done(); iter.Next()) {
|
||||
nsDataHashtable<nsStringHashKey, nsString>& variables =
|
||||
aRuleData->mVariables->mVariables;
|
||||
const nsAString& name = iter.Key();
|
||||
nsString value = iter.UserData();
|
||||
nsString valueSource;
|
||||
SetRevertLayerData(valueSource, aRuleData);
|
||||
if (value.EqualsLiteral(REVERT_LAYER_VALUE)) {
|
||||
value = valueSource;
|
||||
aRuleData->mConditions.SetUncacheable();
|
||||
}
|
||||
|
||||
nsString existingValue;
|
||||
if (variables.Get(name, &existingValue)) {
|
||||
if (IsRevertLayerValue(existingValue)) {
|
||||
if (ShouldIgnoreForRevertLayerValue(existingValue, aRuleData)) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
nsString sourceValue;
|
||||
if (aRuleData->mVariables->mRevertLayerSources.Get(name,
|
||||
&sourceValue) &&
|
||||
!ShouldIgnoreForRevertLayerValue(sourceValue, aRuleData)) {
|
||||
RevertLayerFallbackList* fallbacks =
|
||||
aRuleData->mVariables->mRevertLayerFallbacks.LookupOrAdd(name);
|
||||
RevertLayerFallback* fallback = fallbacks->mItems.AppendElement();
|
||||
fallback->mValue = value;
|
||||
fallback->mSource = valueSource;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
variables.Put(name, value);
|
||||
if (ValueMightResolveToRevertLayer(value)) {
|
||||
aRuleData->mVariables->mRevertLayerSources.Put(name, valueSource);
|
||||
} else {
|
||||
aRuleData->mVariables->mRevertLayerSources.Remove(name);
|
||||
aRuleData->mVariables->mRevertLayerFallbacks.Remove(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,8 +434,9 @@ CSSVariableDeclarations::AddVariablesToResolver(
|
||||
false);
|
||||
} else if (value.EqualsLiteral(INHERIT_VALUE) ||
|
||||
value.EqualsLiteral(UNSET_VALUE) ||
|
||||
value.EqualsLiteral(REVERT_VALUE)) {
|
||||
// Values of 'inherit', 'unset', and 'revert' don't need any handling,
|
||||
value.EqualsLiteral(REVERT_VALUE) ||
|
||||
IsRevertLayerValue(value)) {
|
||||
// Values of 'inherit', 'unset', 'revert', and 'revert-layer' don't need any handling,
|
||||
// since it means we just need to keep whatever value is currently in
|
||||
// the resolver. This is because the specified variable declarations
|
||||
// already have only the winning declaration for the variable and no
|
||||
@@ -190,6 +453,83 @@ CSSVariableDeclarations::AddVariablesToResolver(
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CSSVariableDeclarations::ResolveRevertLayerFallbacks(
|
||||
const CSSVariableValues* aInherited,
|
||||
CSSVariableValues* aOutput) const
|
||||
{
|
||||
for (auto iter = mRevertLayerSources.ConstIter();
|
||||
!iter.Done(); iter.Next()) {
|
||||
const nsAString& name = iter.Key();
|
||||
nsString value;
|
||||
nsCSSTokenSerializationType firstToken, lastToken;
|
||||
if (!aOutput->Get(name, value, firstToken, lastToken)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!IsComputedRevertLayerValue(value)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const RevertLayerFallbackList* fallbacks = mRevertLayerFallbacks.Get(name);
|
||||
if (fallbacks) {
|
||||
nsString sourceValue = iter.UserData();
|
||||
bool foundFallback = false;
|
||||
for (uint32_t i = 0, n = fallbacks->mItems.Length(); i < n; i++) {
|
||||
const RevertLayerFallback& fallback = fallbacks->mItems[i];
|
||||
if (ShouldIgnoreForRevertLayerSourceValue(sourceValue,
|
||||
fallback.mSource)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (IsRevertLayerValue(fallback.mValue)) {
|
||||
sourceValue = fallback.mSource;
|
||||
continue;
|
||||
}
|
||||
|
||||
CSSVariableValues inheritedValues(*aOutput);
|
||||
if (aInherited->Get(name, value, firstToken, lastToken)) {
|
||||
inheritedValues.Put(name, value, firstToken, lastToken);
|
||||
} else {
|
||||
inheritedValues.Remove(name);
|
||||
}
|
||||
|
||||
CSSVariableDeclarations fallbackDeclarations;
|
||||
fallbackDeclarations.mVariables.Put(name, fallback.mValue);
|
||||
|
||||
CSSVariableValues fallbackValues;
|
||||
CSSVariableResolver resolver(&fallbackValues);
|
||||
resolver.Resolve(&inheritedValues, &fallbackDeclarations);
|
||||
|
||||
if (!fallbackValues.Get(name, value, firstToken, lastToken)) {
|
||||
aOutput->Remove(name);
|
||||
foundFallback = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (IsComputedRevertLayerValue(value)) {
|
||||
sourceValue = fallback.mSource;
|
||||
continue;
|
||||
}
|
||||
|
||||
aOutput->Put(name, value, firstToken, lastToken);
|
||||
foundFallback = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (foundFallback) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (aInherited->Get(name, value, firstToken, lastToken)) {
|
||||
aOutput->Put(name, value, firstToken, lastToken);
|
||||
} else {
|
||||
aOutput->Remove(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
CSSVariableDeclarations::SizeOfIncludingThis(
|
||||
mozilla::MallocSizeOf aMallocSizeOf) const
|
||||
@@ -200,6 +540,22 @@ CSSVariableDeclarations::SizeOfIncludingThis(
|
||||
n += iter.Key().SizeOfExcludingThisIfUnshared(aMallocSizeOf);
|
||||
n += iter.Data().SizeOfExcludingThisIfUnshared(aMallocSizeOf);
|
||||
}
|
||||
n += mRevertLayerSources.ShallowSizeOfExcludingThis(aMallocSizeOf);
|
||||
for (auto iter = mRevertLayerSources.ConstIter(); !iter.Done(); iter.Next()) {
|
||||
n += iter.Key().SizeOfExcludingThisIfUnshared(aMallocSizeOf);
|
||||
n += iter.Data().SizeOfExcludingThisIfUnshared(aMallocSizeOf);
|
||||
}
|
||||
n += mRevertLayerFallbacks.ShallowSizeOfExcludingThis(aMallocSizeOf);
|
||||
for (auto iter = mRevertLayerFallbacks.ConstIter(); !iter.Done(); iter.Next()) {
|
||||
n += iter.Key().SizeOfExcludingThisIfUnshared(aMallocSizeOf);
|
||||
const RevertLayerFallbackList* list = iter.UserData();
|
||||
n += aMallocSizeOf(list);
|
||||
n += list->mItems.ShallowSizeOfExcludingThis(aMallocSizeOf);
|
||||
for (uint32_t i = 0, len = list->mItems.Length(); i < len; i++) {
|
||||
n += list->mItems[i].mValue.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
|
||||
n += list->mItems[i].mSource.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,10 +7,13 @@
|
||||
#ifndef mozilla_CSSVariableDeclarations_h
|
||||
#define mozilla_CSSVariableDeclarations_h
|
||||
|
||||
#include "nsClassHashtable.h"
|
||||
#include "nsDataHashtable.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
namespace mozilla {
|
||||
class CSSVariableResolver;
|
||||
class CSSVariableValues;
|
||||
} // namespace mozilla
|
||||
struct nsRuleData;
|
||||
|
||||
@@ -43,7 +46,8 @@ public:
|
||||
eInitial, // 'initial'
|
||||
eInherit, // 'inherit'
|
||||
eUnset, // 'unset'
|
||||
eRevert // 'revert'
|
||||
eRevert, // 'revert'
|
||||
eRevertLayer // 'revert-layer'
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -97,6 +101,15 @@ public:
|
||||
*/
|
||||
void PutRevert(const nsAString& aName);
|
||||
|
||||
/**
|
||||
* Adds or modifies an existing entry in this set of variable declarations
|
||||
* to have the value 'revert-layer'.
|
||||
*
|
||||
* @param aName The variable name (not including any "--" prefix that would
|
||||
* be part of the custom property name) whose value is to be set.
|
||||
*/
|
||||
void PutRevertLayer(const nsAString& aName);
|
||||
|
||||
/**
|
||||
* Adds or modifies an existing entry in this set of variable declarations
|
||||
* to have a token stream value.
|
||||
@@ -132,15 +145,36 @@ public:
|
||||
*/
|
||||
void AddVariablesToResolver(CSSVariableResolver* aResolver) const;
|
||||
|
||||
/**
|
||||
* Applies stored lower-priority declarations for custom property values that
|
||||
* resolved to 'revert-layer'.
|
||||
*/
|
||||
void ResolveRevertLayerFallbacks(const CSSVariableValues* aInherited,
|
||||
CSSVariableValues* aOutput) const;
|
||||
|
||||
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
|
||||
|
||||
private:
|
||||
struct RevertLayerFallback
|
||||
{
|
||||
nsString mValue;
|
||||
nsString mSource;
|
||||
};
|
||||
|
||||
struct RevertLayerFallbackList
|
||||
{
|
||||
nsTArray<RevertLayerFallback> mItems;
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds all the variable declarations from aOther into this object.
|
||||
*/
|
||||
void CopyVariablesFrom(const CSSVariableDeclarations& aOther);
|
||||
|
||||
nsDataHashtable<nsStringHashKey, nsString> mVariables;
|
||||
nsDataHashtable<nsStringHashKey, nsString> mRevertLayerSources;
|
||||
nsClassHashtable<nsStringHashKey, RevertLayerFallbackList>
|
||||
mRevertLayerFallbacks;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -121,6 +121,21 @@ CSSVariableValues::Put(const nsAString& aName,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CSSVariableValues::Remove(const nsAString& aName)
|
||||
{
|
||||
size_t id;
|
||||
if (!mVariableIDs.Get(aName, &id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mVariables.RemoveElementAt(id);
|
||||
mVariableIDs.Clear();
|
||||
for (size_t i = 0, n = mVariables.Length(); i < n; i++) {
|
||||
mVariableIDs.Put(mVariables[i].mVariableName, i);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CSSVariableValues::CopyVariablesFrom(const CSSVariableValues& aOther)
|
||||
{
|
||||
|
||||
@@ -94,6 +94,11 @@ public:
|
||||
nsCSSTokenSerializationType aFirstToken,
|
||||
nsCSSTokenSerializationType aLastToken);
|
||||
|
||||
/**
|
||||
* Removes an entry in this set of variable values.
|
||||
*/
|
||||
void Remove(const nsAString& aName);
|
||||
|
||||
/**
|
||||
* Copies the variables from this object into aResolver, marking them as
|
||||
* computed, inherited values.
|
||||
|
||||
@@ -576,6 +576,7 @@ Declaration::GetPropertyValueInternal(
|
||||
const nsCSSValue* tokenStream = nullptr;
|
||||
uint32_t totalCount = 0, importantCount = 0,
|
||||
initialCount = 0, inheritCount = 0, unsetCount = 0, revertCount = 0,
|
||||
revertLayerCount = 0,
|
||||
matchingTokenStreamCount = 0, nonMatchingTokenStreamCount = 0;
|
||||
CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(p, aProperty,
|
||||
CSSEnabledState::eForAllContent) {
|
||||
@@ -603,6 +604,8 @@ Declaration::GetPropertyValueInternal(
|
||||
++unsetCount;
|
||||
} else if (val->GetUnit() == eCSSUnit_Revert) {
|
||||
++revertCount;
|
||||
} else if (val->GetUnit() == eCSSUnit_RevertLayer) {
|
||||
++revertLayerCount;
|
||||
} else if (val->GetUnit() == eCSSUnit_TokenStream) {
|
||||
if (val->GetTokenStreamValue()->mShorthandPropertyID == aProperty) {
|
||||
tokenStream = val;
|
||||
@@ -640,9 +643,19 @@ Declaration::GetPropertyValueInternal(
|
||||
nsCSSValue::eNormalized);
|
||||
return;
|
||||
}
|
||||
if (revertLayerCount == totalCount) {
|
||||
// Simplify serialization below by serializing revert-layer up-front.
|
||||
nsCSSValue revertLayer;
|
||||
revertLayer.SetRevertLayerValue();
|
||||
revertLayer.AppendToString(eCSSProperty_UNKNOWN, aValue,
|
||||
nsCSSValue::eNormalized);
|
||||
return;
|
||||
}
|
||||
if (initialCount != 0 || inheritCount != 0 || unsetCount != 0 ||
|
||||
revertCount != 0 || nonMatchingTokenStreamCount != 0) {
|
||||
// Case (2): partially initial, inherit, unset, revert, or token stream.
|
||||
revertCount != 0 || revertLayerCount != 0 ||
|
||||
nonMatchingTokenStreamCount != 0) {
|
||||
// Case (2): partially initial, inherit, unset, revert, revert-layer,
|
||||
// or token stream.
|
||||
return;
|
||||
}
|
||||
if (tokenStream) {
|
||||
@@ -1535,6 +1548,7 @@ Declaration::GetPropertyValueInternal(
|
||||
case eCSSUnit_Initial:
|
||||
case eCSSUnit_Unset:
|
||||
case eCSSUnit_Revert:
|
||||
case eCSSUnit_RevertLayer:
|
||||
return true;
|
||||
case eCSSUnit_Enumerated:
|
||||
// return false if there is a fallback value or <overflow-position>
|
||||
@@ -1749,6 +1763,10 @@ Declaration::AppendVariableAndValueToString(const nsAString& aName,
|
||||
aResult.AppendLiteral("revert");
|
||||
break;
|
||||
|
||||
case CSSVariableDeclarations::eRevertLayer:
|
||||
aResult.AppendLiteral("revert-layer");
|
||||
break;
|
||||
|
||||
default:
|
||||
MOZ_ASSERT(false, "unexpected variable value type");
|
||||
}
|
||||
@@ -1989,6 +2007,10 @@ Declaration::GetVariableValue(const nsAString& aName, nsAString& aValue) const
|
||||
aValue.AppendLiteral("revert");
|
||||
break;
|
||||
|
||||
case CSSVariableDeclarations::eRevertLayer:
|
||||
aValue.AppendLiteral("revert-layer");
|
||||
break;
|
||||
|
||||
default:
|
||||
MOZ_ASSERT(false, "unexpected variable value type");
|
||||
}
|
||||
@@ -2059,6 +2081,11 @@ Declaration::AddVariable(const nsAString& aName,
|
||||
variables->PutRevert(aName);
|
||||
break;
|
||||
|
||||
case CSSVariableDeclarations::eRevertLayer:
|
||||
MOZ_ASSERT(aValue.IsEmpty());
|
||||
variables->PutRevertLayer(aName);
|
||||
break;
|
||||
|
||||
default:
|
||||
MOZ_ASSERT(false, "unexpected aType value");
|
||||
}
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
#include "nsIFrame.h"
|
||||
#include "gfx2DGlue.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::css;
|
||||
using namespace mozilla::gfx;
|
||||
@@ -39,6 +41,35 @@ using nsStyleTransformMatrix::Decompose2DMatrix;
|
||||
using nsStyleTransformMatrix::Decompose3DMatrix;
|
||||
using nsStyleTransformMatrix::ShearType;
|
||||
|
||||
static bool
|
||||
GetAspectRatioAnimationValue(const nsCSSValuePair* aPair,
|
||||
bool& aAuto,
|
||||
float& aRatio)
|
||||
{
|
||||
aAuto = aPair->mXValue.GetUnit() == eCSSUnit_Auto;
|
||||
if (aAuto) {
|
||||
if (aPair->mYValue.GetUnit() != eCSSUnit_Pair) {
|
||||
return false;
|
||||
}
|
||||
aPair = &aPair->mYValue.GetPairValue();
|
||||
}
|
||||
|
||||
if (aPair->mXValue.GetUnit() != eCSSUnit_Number ||
|
||||
aPair->mYValue.GetUnit() != eCSSUnit_Number) {
|
||||
return false;
|
||||
}
|
||||
|
||||
float width = aPair->mXValue.GetFloatValue();
|
||||
float height = aPair->mYValue.GetFloatValue();
|
||||
if (width <= 0.0f || height <= 0.0f ||
|
||||
!std::isfinite(width) || !std::isfinite(height)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aRatio = width / height;
|
||||
return std::isfinite(aRatio) && aRatio > 0.0f;
|
||||
}
|
||||
|
||||
// HELPER METHODS
|
||||
// --------------
|
||||
/*
|
||||
@@ -1243,6 +1274,21 @@ StyleAnimationValue::ComputeDistance(nsCSSPropertyID aProperty,
|
||||
case eUnit_CSSValuePair: {
|
||||
const nsCSSValuePair *pair1 = aStartValue.GetCSSValuePairValue();
|
||||
const nsCSSValuePair *pair2 = aEndValue.GetCSSValuePairValue();
|
||||
if (aProperty == eCSSProperty_aspect_ratio) {
|
||||
bool auto1;
|
||||
bool auto2;
|
||||
float ratio1;
|
||||
float ratio2;
|
||||
if (!GetAspectRatioAnimationValue(pair1, auto1, ratio1) ||
|
||||
!GetAspectRatioAnimationValue(pair2, auto2, ratio2) ||
|
||||
auto1 != auto2) {
|
||||
return false;
|
||||
}
|
||||
aDistance = Abs(std::log(double(ratio2)) -
|
||||
std::log(double(ratio1)));
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCSSUnit unit[2];
|
||||
unit[0] = GetCommonUnit(aProperty, pair1->mXValue.GetUnit(),
|
||||
pair2->mXValue.GetUnit());
|
||||
@@ -2821,6 +2867,42 @@ StyleAnimationValue::AddWeighted(nsCSSPropertyID aProperty,
|
||||
return true;
|
||||
}
|
||||
case eUnit_CSSValuePair: {
|
||||
if (aProperty == eCSSProperty_aspect_ratio) {
|
||||
bool auto1;
|
||||
bool auto2;
|
||||
float ratio1;
|
||||
float ratio2;
|
||||
if (!GetAspectRatioAnimationValue(aValue1.GetCSSValuePairValue(),
|
||||
auto1, ratio1) ||
|
||||
!GetAspectRatioAnimationValue(aValue2.GetCSSValuePairValue(),
|
||||
auto2, ratio2) ||
|
||||
auto1 != auto2 ||
|
||||
std::abs((aCoeff1 + aCoeff2) - 1.0) > 0.000001) {
|
||||
return false;
|
||||
}
|
||||
|
||||
float resultRatio =
|
||||
std::exp(aCoeff1 * std::log(double(ratio1)) +
|
||||
aCoeff2 * std::log(double(ratio2)));
|
||||
nsCSSValue width;
|
||||
width.SetFloatValue(resultRatio, eCSSUnit_Number);
|
||||
nsCSSValue height;
|
||||
height.SetFloatValue(1.0f, eCSSUnit_Number);
|
||||
nsCSSValue ratio;
|
||||
ratio.SetPairValue(width, height);
|
||||
|
||||
auto result = MakeUnique<nsCSSValuePair>();
|
||||
if (auto1) {
|
||||
result->mXValue.SetAutoValue();
|
||||
result->mYValue = ratio;
|
||||
} else {
|
||||
*result = ratio.GetPairValue();
|
||||
}
|
||||
aResultValue.SetAndAdoptCSSValuePairValue(result.release(),
|
||||
eUnit_CSSValuePair);
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t restrictions = nsCSSProps::ValueRestrictions(aProperty);
|
||||
Maybe<nsCSSValuePair> result =
|
||||
AddCSSValuePair(aProperty, restrictions,
|
||||
@@ -4031,6 +4113,33 @@ StyleAnimationValue::ExtractComputedValue(nsCSSPropertyID aProperty,
|
||||
break;
|
||||
}
|
||||
|
||||
case eCSSProperty_aspect_ratio: {
|
||||
const StyleAspectRatio& ratio =
|
||||
static_cast<const nsStylePosition*>(styleStruct)->mAspectRatio;
|
||||
if (!ratio.HasRatio()) {
|
||||
aComputedValue.SetAutoValue();
|
||||
break;
|
||||
}
|
||||
|
||||
nsCSSValue width;
|
||||
width.SetFloatValue(ratio.mWidth, eCSSUnit_Number);
|
||||
nsCSSValue height;
|
||||
height.SetFloatValue(ratio.mHeight, eCSSUnit_Number);
|
||||
nsCSSValue ratioValue;
|
||||
ratioValue.SetPairValue(width, height);
|
||||
|
||||
auto pair = MakeUnique<nsCSSValuePair>();
|
||||
if (ratio.mAuto) {
|
||||
pair->mXValue.SetAutoValue();
|
||||
pair->mYValue = ratioValue;
|
||||
} else {
|
||||
*pair = ratioValue.GetPairValue();
|
||||
}
|
||||
aComputedValue.SetAndAdoptCSSValuePairValue(pair.release(),
|
||||
eUnit_CSSValuePair);
|
||||
break;
|
||||
}
|
||||
|
||||
case eCSSProperty_border_spacing: {
|
||||
const nsStyleTableBorder *styleTableBorder =
|
||||
static_cast<const nsStyleTableBorder*>(styleStruct);
|
||||
|
||||
@@ -489,7 +489,7 @@ public:
|
||||
void SetNoneValue();
|
||||
void SetIntValue(int32_t aInt, Unit aUnit);
|
||||
template<typename T,
|
||||
typename = typename std::enable_if<std::is_enum<T>::value>::type>
|
||||
typename = typename std::enable_if_t<std::is_enum_v<T>>>
|
||||
void SetIntValue(T aInt, Unit aUnit)
|
||||
{
|
||||
static_assert(mozilla::EnumTypeFitsWithin<T, int32_t>::value,
|
||||
|
||||
@@ -26,6 +26,8 @@ StyleSheet::StyleSheet(css::SheetParsingMode aParsingMode)
|
||||
, mOwningNode(nullptr)
|
||||
, mParsingMode(aParsingMode)
|
||||
, mDisabled(false)
|
||||
, mConstructed(false)
|
||||
, mDisallowModification(false)
|
||||
, mDocumentAssociationMode(NotOwnedByDocument)
|
||||
{
|
||||
}
|
||||
@@ -38,6 +40,8 @@ StyleSheet::StyleSheet(const StyleSheet& aCopy,
|
||||
, mOwningNode(aOwningNodeToUse)
|
||||
, mParsingMode(aCopy.mParsingMode)
|
||||
, mDisabled(aCopy.mDisabled)
|
||||
, mConstructed(aCopy.mConstructed)
|
||||
, mDisallowModification(false)
|
||||
// We only use this constructor during cloning. It's the cloner's
|
||||
// responsibility to notify us if we end up being owned by a document.
|
||||
, mDocumentAssociationMode(NotOwnedByDocument)
|
||||
@@ -254,6 +258,7 @@ StyleSheet::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
|
||||
sheet->SetURIs(documentURI, nullptr, baseURI);
|
||||
sheet->SetPrincipal(principal);
|
||||
sheet->SetComplete();
|
||||
sheet->SetConstructed();
|
||||
|
||||
return sheet.forget();
|
||||
}
|
||||
@@ -290,6 +295,17 @@ StyleSheet::DeleteRule(uint32_t aIndex,
|
||||
AsConcrete()->DeleteRuleInternal(aIndex, aRv);
|
||||
}
|
||||
|
||||
void
|
||||
StyleSheet::ReplaceSync(const nsAString& aText, ErrorResult& aRv)
|
||||
{
|
||||
if (!IsConstructed() || IsModificationDisallowed()) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_ALLOWED_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
AsConcrete()->ReplaceSyncInternal(aText, aRv);
|
||||
}
|
||||
|
||||
int32_t
|
||||
StyleSheet::AddRule(const nsAString& aSelector, const nsAString& aBlock,
|
||||
const Optional<uint32_t>& aIndex,
|
||||
|
||||
Loaded 100 of 768 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user