Compare commits

..
112 Commits
Author SHA1 Message Date
Moonchild 4d5b1cc5d8 Merge branch 'nss-3.125-port' 2026-07-28 10:50:50 +02:00
Moonchild 0e521f6302 Bump NSS (UXP) patch level. 2026-07-28 10:10:27 +02:00
Moonchild 9cacfcff57 Merge remote-tracking branch 'dbsoft/flex-button-fix2' 2026-07-28 10:08:00 +02:00
John Schanck 21ad7adc90 Bug 2043887 - guard against integer overflow in CERT_Hexify. 2026-07-28 10:03:44 +02:00
Benjamin Beurdouche 9a29430751 Bug 2027353 - clamp input.len to testString size in pk11_mergeSecretKey. 2026-07-28 09:59:51 +02:00
Benjamin Beurdouche 481d4868b0 Bug 2029433 - Bounds-check wrap index in PK11_GetWrapKey to match PK11_SetWrapKey. 2026-07-28 09:57:10 +02:00
Anna Weine d148c11717 Bug 2028954 - CERT_DecodeAVAValue — Integer Overflow in Output Buffer Sizing. 2026-07-28 09:53:26 +02:00
Moonchild bc322e58f8 Bug 2027364 - Set tail pointer to null in static slot lists when deallocating. 2026-07-28 09:22:56 +02:00
John Schanck e48a6f26a5 Bug 2032110 - fix two integer overflows on LLP64 systems. 2026-07-27 23:58:14 +02:00
John Schanck d85edd01df Bug 2030102 - avoid leaving a dangling ss->sec.ci.sid on allocation failure. 2026-07-27 23:49:55 +02:00
Maurice Dauer 296379d751 Bug 2027325 - Reject empty nickname in PK11_TraverseCertsForNicknameInSlot. 2026-07-27 23:46:32 +02:00
Moonchild 7ba9fc2801 Bug 2030563 - Validate CKA_CERTIFICATE_TYPE ulValueLen in nss_cert_type_from_ck_attrib. 2026-07-27 23:22:58 +02:00
Brian Smith a9ac8b390f Issue #3153 - Make sure buttons report a definite size for flex containers.
Second try, this time ONLY do it for flex container or grids.
This should prevent layout problems in non-flex scenarios.
2026-07-27 12:36:24 -05:00
Benjamin Beurdouche 71c0f8246c Bug 2029807 - Guard padding read against empty output in SEC_PKCS7DecryptContents. 2026-07-27 19:12:42 +02:00
Benjamin Beurdouche 6cda35442f Bug 2027346 - validate encoded EC params length and tag in SECKEY_ECParamsToKeySize/BasePointOrderLen. 2026-07-27 19:05:33 +02:00
Benjamin Beurdouche 1dba423327 Bug 2027371 - rewrite labelLen bound in tls13_HkdfExpandLabelGeneral to avoid unsigned overflow. 2026-07-27 18:56:08 +02:00
Benjamin Beurdouche e2af0b28bf Bug 2027373 - guard space subtraction in ssl_CallCustomExtensionSenders. 2026-07-27 18:51:32 +02:00
Benjamin Beurdouche 5ea9b7b80a Bug 2029901 - Guard against keySize overflow in IKE PRF/PRF+ output sizing. 2026-07-27 18:44:55 +02:00
Benjamin Beurdouche b799e100ad Bug 2027362 - bound usageCount in PK11_UnwrapPrivKey to keyTemplate capacity. 2026-07-27 18:39:10 +02:00
Benjamin Beurdouche 1c500a6abb Bug 2027349 - reject empty nickname in PK11_TraverseCertsForNicknameInSlot. 2026-07-27 18:27:47 +02:00
Moonchild b909fccc92 Revert "Issue #3153 - Make sure buttons report a definite size for flex containers."
This reverts commit 3e223cbfb4.
2026-07-27 17:59:43 +02:00
Moonchild abddee43b4 Merge remote-tracking branch 'dbsoft/flex-button-fix' 2026-07-27 14:41:27 +02:00
Moonchild 49d184e550 [network] Fix CacheEntry::mDoomCallback data race. 2026-07-27 14:32:51 +02:00
Brian Smith 3e223cbfb4 Issue #3153 - Make sure buttons report a definite size for flex containers. 2026-07-27 05:38:09 -05:00
Moonchild dd9099a7d3 [layout] Fix nsFrameSetFrame primary frame handling of replicated children. 2026-07-26 19:55:49 +02:00
Moonchild 31558a1521 Merge pull request 'Issue #3061 Follow-up: Remove network tickler prefs' (#3151) from Shadow/UXP-contrib:contrib into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3151
2026-07-26 15:45:08 +00:00
Shadow 0e683bf699 Issue #3061 Follow-up: Remove network tickler prefs 2026-07-26 15:39:39 +00:00
Moonchild 6459dec5bb [DOM media] Perform more thorough checks on video regions. 2026-07-26 15:04:18 +02:00
az 0e930fba3f Bug 2045742 2026-07-26 10:08:13 +02:00
Moonchild 3b683bbe59 Merge pull request 'Align aspect-ratio to spec' (#3150) from Basilisk-Dev/UXP-contrib:css-aspect-ratio into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3150
2026-07-26 07:06:00 +00:00
Basilisk-Dev 0042e54c38 Issue #2404 - Split aspect ratio enum types into a separate header to fix compilation issues 2026-07-25 12:24:15 -04:00
Andrew McCreight e75201f7d1 Bug 2049523 - Make ToJSValue for float consistent with double. 2026-07-25 17:04:14 +02:00
Moonchild 28c47723b2 Fix comment (nit) 2026-07-25 16:12:08 +02:00
Randell Jesup 3d872ff7b0 Bug 2029734: Flush before calling sctp_process_init() 2026-07-25 14:52:29 +02:00
Moonchild beb684c29e No issue - Use strnlen instead of strnlen_s.
Apparently, GCC doesn't like the _s variants.
2026-07-25 13:08:15 +02:00
Moonchild 775588b75d [image] Make sure the image was fully and cleanly decoded before finalizing its animation state as complete. 2026-07-25 10:01:55 +02:00
Basilisk-Dev 8a2a5d837c Issue #2404 - Fix aspect ratio sizing for grid items 2026-07-25 00:58:20 -04:00
Basilisk-Dev 8add755c81 Issue #2404 - Improvements to CSS aspect-ratio spec compliance 2026-07-25 00:57:58 -04:00
Moonchild 257c64567e [parser] Associate image elements with form only if the form and the intended parent are in the same tree. 2026-07-24 21:12:04 +02:00
Moonchild d0b61d4a68 No issue - CallUpdateWindow is [[nodiscard]], but we don't need to use
the result here.
2026-07-24 19:29:00 +02:00
Moonchild 3b5f50cc35 Merge pull request 'No Issue - Remove the half-life experiment in HTTP cache' (#3149) from Shadow/UXP-contrib:master into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3149
2026-07-24 14:32:21 +00:00
Moonchild 27c6a7f477 [DOM media] Stop accepting audio samples with too low sample rates.
This sets the floor to 8kHz audio, which is generally considered to be
the lowest acceptable "phone quality"/"walkie-talkie" audio rate.
Audio outside the range will refuse to decode after this commit and give
a console error.
This avoids a whole class of potential bugs.
2026-07-24 14:52:40 +02:00
Moonchild c65f84214e [layout] Add corner-case correctness check in DottedCornerFinder::FindBestOverlap. 2026-07-24 13:17:54 +02:00
Moonchild a317c65fd7 [network] Add usrsctp TSN gap check. 2026-07-24 12:58:20 +02:00
Shadow 0ec35ce534 No Issue - Remove the half-life experiment in HTTP cache
Reviewed-on: https://repo.palemoon.org/Shadow/UXP-contrib/pulls/1
2026-07-24 09:49:48 +00:00
Moonchild bf0c040722 [js] Clamp length of regexp captures array for dollar substitution. 2026-07-22 22:37:50 +02:00
Moonchild ebadd51401 [js] Initialize BaselineFrame return value slot in OnLeaveBaselineFrame. 2026-07-22 20:26:07 +02:00
Moonchild 5ed0bf8b44 [DOM] Make parser update form owner properly 2026-07-22 17:12:32 +02:00
Moonchild f877c1dba5 [gfx] Hold a strong ref during GetFontAt lookup. 2026-07-22 10:27:53 +02:00
Moonchild 4c14f8f89b [gfx] Add bounds checks and limit reverse scanning of ligature data. 2026-07-22 09:43:54 +02:00
Moonchild c119728965 Merge pull request 'Implement CSSStyleSheet replaceSync' (#3145) from Basilisk-Dev/UXP-contrib:replacesync into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3145
2026-07-22 06:02:21 +00:00
Moonchild fa55b9c2e8 [js] Guard against OOB string sizes in internal Printf 2026-07-22 01:39:03 +02:00
Basilisk-Dev 16aba76fc5 Issue #3144 - Implement CSSStyleSheet replaceSync 2026-07-21 04:23:19 -04:00
Moonchild 995def99cd No issue - Exclude some files from the preprocessor that don't have directives in them. 2026-07-19 15:57:10 +02:00
Moonchild 923e52789c Merge pull request 'Convert std::*<T>::value/::type to _v and _t suffixes.' (#3143) from 1803 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3143
2026-07-19 07:40:35 +00:00
Moonchild 22d945430b Issue #3061 - Remove network tickler.
Resolves #3061
2026-07-19 08:17:05 +02:00
Moonchild 65d7d93760 Issue #1803 - Convert std::*<T>::value/::type to _v and _t suffixes.
This excludes uses in third-party libs in our tree.
2026-07-15 11:20:06 +02:00
Moonchild dfd0ea4e8a Merge pull request 'implement URL.parse()' (#3141) from Basilisk-Dev/UXP-contrib:urlparse into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3141
2026-07-14 21:05:40 +00:00
Basilisk-Dev 12a49709cb Issue #3140 - implement URL.parse() 2026-07-14 16:07:45 -04:00
Moonchild 2a70c8a6f0 Merge pull request 'Implement CSS4 revert-layer keyword' (#3139) from Basilisk-Dev/UXP-contrib:revert-layer into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3139
2026-07-13 12:44:06 +00:00
Moonchild 1f639d78ca Merge pull request 'Allow Skia on Mac OS X 10.5 Leopard / big endian PPC' (#3138) from Jazzzny/UXP:skia-leopard-ppc into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3138
2026-07-13 12:43:15 +00:00
Basilisk-Dev 65e8245153 Issue #2829 - Regenerate devtools CSS database for revert-layer 2026-07-11 10:41:52 -04:00
Basilisk-Dev bce5dbad0b Issue #2829 - Use layer index naming for revert-layer metadata 2026-07-11 10:41:46 -04:00
Basilisk-Dev 0b25b5f8db Issue #2829 - Handle revert-layer variable fallbacks 2026-07-10 09:59:20 -04:00
Basilisk-Dev 7345874098 Issue #2829 - Implement CSS revert-layer cascade rollback 2026-07-10 09:59:14 -04:00
Basilisk-Dev edb82fd1c9 Issue #2829 - Support revert-layer in CSS-wide parsing 2026-07-10 09:59:03 -04:00
Jazzzny 35ebdcac66 Fix build issues in Skia code 2026-07-09 12:32:44 -04:00
Jazzzny a095661e86 Use Skia macros where appropriate 2026-07-08 13:43:07 -04:00
Jazzzny 205a0d66bb Add support for big endian in Skia 2026-07-08 04:38:00 -04:00
Jazzzny 54945a0808 Unblock Skia for big endian 2026-07-08 04:38:00 -04:00
Jazzzny 84c1eedac6 Fixes for Skia on 10.5 2026-07-08 04:38:00 -04:00
Moonchild ddf5d6256e Whitespace fix 2026-07-03 09:24:24 +02:00
Moonchild 0eae777fd0 Issue #3132 Follow-up: only include gtk2xtbin.h on GTK targets.
PR #3133 caused build breakage on non-gtk platforms by unconditionally
including the header (because the def defaults to true in configure)

This also reorganizes the configure script to add a check for
MOZ_WIDGET_GTK (hoisted up a little) so the new configure entry is
simply ignored on non-GTK targets.
2026-07-03 09:19:54 +02:00
Moonchild b2594a4ace Merge pull request 'Revert gtk file dialog change and set default to cancel' (#3137) from 3136 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3137
2026-06-30 13:54:19 +00:00
Moonchild ce61835a81 revert 8a2a9ead92
revert [gtk] Default the file dialog operation to cancelling the operation.

While this could be an annoying default for users expecting fast-track
dialog operations with hitting enter, it avoids potential social
engineering attacks and unintended file operations.
2026-06-30 13:53:18 +00:00
Moonchild 30e29845c4 Merge pull request 'Decouple NPAPI from GTK2' (#3133) from Basilisk-Dev/UXP-contrib:npapi-no-gtk2 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3133
2026-06-30 13:51:11 +00:00
Basilisk-Dev d8662c5dd9 Issue #3132 - use ENABLE check for npapi gtk2 builds instead of a dedicated DISABLE check to match other config options 2026-06-30 09:15:45 -04:00
Moonchild 8a2a9ead92 [gtk] Default the file dialog operation to cancelling the operation.
While this could be an annoying default for users expecting fast-track
dialog operations with hitting enter, it avoids potential social
engineering attacks and unintended file operations.
2026-06-28 12:09:07 +02:00
Moonchild efdbd34b0b Revert "Bug 2033848 - Use non-default response ID for GTK file picker accept button. r=stransky"
This reverts commit 789e976ace.
2026-06-28 12:08:59 +02:00
Moonchild d2fa69f593 Merge pull request 'Import missing libpng files for loongarch and plug them into moz.build' (#3135) from Basilisk-Dev/UXP-contrib:png-loongarch-fix into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3135
2026-06-27 07:25:51 +00:00
Basilisk-Dev 18d0a1a525 Issue #3134 - Import missing libpng files for loongarch and plug them into moz.build 2026-06-26 14:48:51 -04:00
Basilisk-Dev 0a5e50a9fe Issue #3132 - Resolve GTK3 ATK bridge dynamically 2026-06-26 13:49:15 -04:00
Basilisk-Dev 3f5b7ed020 Issue #3132 - Add GTK2 NPAPI build toggle 2026-06-26 13:09:49 -04:00
Moonchild 9d9802c660 Issue #3129 - Follow-up: Add aarch64 to platforms enabling Neon in libpng. 2026-06-26 16:58:21 +02:00
Moonchild 27c579652a Issue #3122 - Stop using <base> element in json viewer.
Resolves #3122
2026-06-23 21:09:02 +02:00
Moonchild 8ffa6b3c13 Issue #3129 - Add palette_neon_intrinsics.c to moz.build 2026-06-23 10:23:17 +02:00
Moonchild 83f6efc33d Issue #3122 - Put base paths in the json viewer client deps.
The dependency modules are requested early. Seems CSP can block baseURL
on these networking requests, so add the base manually to the resource
paths to prevent network requests before the html base element is
resolved and active.
2026-06-22 17:58:21 +02:00
Moonchild 47f1928610 Merge pull request 'Libpng update 1.6.58' (#3125) from libpng-update-1.6.58 into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/3125
2026-06-21 12:14:42 +00:00
Moonchild 7b3d961465 Bump NSS version for adopted changes. 2026-06-19 14:19:43 +02:00
Moonchild 22b2e18d91 [DOM] Clean up WebGL transform feedback validation. 2026-06-19 13:30:35 +02:00
John Schanck f6c9c0c59f Bug 2030564 - add defensive input validation to sftk_compute_ANSI_X9_63_kdf. 2026-06-19 12:56:26 +02:00
John Schanck d8c9d24a9c Bug 2030366 - avoid race with module unloading in NSSTrustDomain_FindTokensByURI. 2026-06-19 12:04:23 +02:00
John Schanck a466b73267 Bug 2029403 - avoid PORT_Strdup in ssl_DecodeResumptionToken. 2026-06-19 10:51:37 +02:00
Julian Descottes 1ce14fb014 [devtools] Consistently show filepicker on first save action from StyleEditor.
Bug 2038133
2026-06-19 10:45:33 +02:00
Moonchild 8bbf60fb38 Issue #3127 - Add trademark notice to the tree.
Resolves #3127
2026-06-19 08:37:27 +02:00
Moonchild f2d7c02290 Apply (hopefully for the last time before 2.0.x) APNG support code.
This commit also removes MOZCHANGES (old and irrelevant information)
This commit also adds a new readme.
2026-06-18 22:57:29 +02:00
Moonchild 65ddfc21b6 Fresh import of libpng 1.6.58 2026-06-18 21:50:35 +02:00
Moonchild 163619de60 [network] Make HttpBaseChannel::mLoadFlags atomic. 2026-06-18 20:32:03 +02:00
Moonchild 29c4d554a0 [gfx] Check more offsets during CFF subsetting.
Also fixes a bunch of whitespace (TAB -> spaces)
2026-06-18 19:35:49 +02:00
Moonchild 3e59569d0b [DOM] Avoid over-optimizing some getter/function calls. 2026-06-18 13:45:20 +02:00
Moonchild fb8483407b [parser] Better align with spec definition of adding nodes. 2026-06-18 13:32:16 +02:00
Moonchild ec8b7f86d0 No issue - Use ImmGCPtr for module meta data visits.
This should make module GCs less touchy.
2026-06-17 23:46:18 +02:00
Moonchild 9899d59010 [DOM media] Zero-initialize ThreadSharedFloatArrayBufferList. 2026-06-17 18:13:15 +02:00
Kui-Feng Lee 789e976ace Bug 2033848 - Use non-default response ID for GTK file picker accept button. r=stransky
Replace GTK_RESPONSE_ACCEPT (-3) with a non-negative application-defined
response ID (kFilePickerAccept = 0) for the accept button in the GTK file
chooser dialog, and remove the gtk_dialog_set_default_response() call.

GTK treats buttons with negative built-in response IDs as candidates for
the dialog's default widget, which activates on Enter key press. By using
a non-negative ID and not calling set_default_response(), the accept button
is no longer pre-selected, preventing a page from tricking the user into
confirming a file upload by holding Enter before the dialog appears.

GTK's file chooser internally emits GTK_RESPONSE_ACCEPT via file_activated_cb
when the user double-clicks a file, so we keep that case in DoneNonPortal()
alongside kFilePickerAccept.
2026-06-17 12:47:03 +02:00
John Schanck d5bf2555a3 Bug 2023478 - improve handling of escape sequences in pk11uri_ParseAttributes. 2026-06-17 12:17:06 +02:00
Moonchild be672813f6 [DOM] Reject too large mLength in MutableBlobStorage::WriteRunnable. 2026-06-16 20:06:25 +02:00
John Schanck 746a7be08c Bug 2030570 - use correct data for ID comparison in transfer_uri_certs_to_collection. 2026-06-16 19:54:44 +02:00
Moonchild c222ee80fa [network] Make keep-alive pref Atomic. 2026-06-16 19:50:55 +02:00
John Schanck 4950bd038d Bug 2029765 - avoid refcount over-release in nssTokenObjectCache error path [@ nssToken_Destroy]. 2026-06-16 18:52:25 +02:00
Nicolas B. Pierron 058336a071 Bug 2029066 - Remove Sinking of Live instructions.
Instruction sinking was made possible by the introduction of recover
instructions, which are moving instructions to be executed on bailout, but this
is only possible for instructions which are not used.

This feature, which is now removed, was made to sink instructions which are
live, but only in a small set of branches, by moving the computation of these
instructions to bailout paths, and to the concerned if branches.

The current implementation never delivered and remained as dead-code for
multiple years, without having a firm benefit on performance oriented
benchmarks.

Thus, this change removes the part of the Sink optimization which deals with
live instructions but keeps the part of the Sink optimization which deals with
instructions which are only used on bailout paths.
2026-06-16 13:37:21 +02:00
John Schanck 6823388a85 Bug 2029803 - add defensive info->len check in PK11_HPKE_SetupS and PK11_HPKE_SetupR. 2026-06-16 09:27:28 +02:00
Moonchild b68d097eb6 Issue #3122 - Exclude local resources from <base> CSP checks.
This avoids local-resource <base> URLs being restricted/nullified by
remote CSP. This aligns the CSP handling with direct requests.

Resolves #3122
2026-06-14 10:08:17 +02:00
233 changed files with 14414 additions and 9189 deletions

No files matched your search

+1 -1
View File
@@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Clobber for Idle GC backout
Clobber for removal of network tickler
+8
View File
@@ -0,0 +1,8 @@
TRADEMARK NOTICE
================
The name "Goanna" and visual representations (logo) have not been
registered by the Copyright owners as a trademark in any jurisdiction.
However, because Goanna has been distributed and maintained world-wide,
continually since 2015, the Copyright owners claim "common-law trademark
protection" in any jurisdiction where common-law trademark is recognized.
+48 -7
View File
@@ -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
+1
View File
@@ -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',
@@ -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;
}
}
+7 -6
View File
@@ -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 = "css/main.css";
style.href = appRoot +"css/main.css";
let script = doc.createElement("script");
script.src = "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';
+1 -1
View File
@@ -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",
+1 -1
View File
@@ -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',
]
+2 -1
View File
@@ -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
@@ -103,12 +103,6 @@ function StyleSheetEditor(styleSheet, win, file, isNew, walker, highlighter) {
}
};
this._styleSheetFilePath = null;
if (styleSheet.href &&
Services.io.extractScheme(this.styleSheet.href) == "file") {
this._styleSheetFilePath = this.styleSheet.href;
}
this._onPropertyChange = this._onPropertyChange.bind(this);
this._onError = this._onError.bind(this);
this._onMediaRuleMatchesChange = this._onMediaRuleMatchesChange.bind(this);
@@ -664,8 +658,7 @@ StyleSheetEditor.prototype = {
if (this._friendlyName) {
defaultName = OS.Path.basename(this._friendlyName);
}
showFilePicker(file || this._styleSheetFilePath, true, this._window,
onFile, defaultName);
showFilePicker(file, true, this._window, onFile, defaultName);
},
/**
@@ -1,98 +1,112 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test that 'Save' function works.
const TESTCASE_URI_HTML = TEST_BASE_HTTP + "simple.html";
const TESTCASE_URI_CSS = TEST_BASE_HTTP + "simple.css";
var tempScope = {};
Components.utils.import("resource://gre/modules/FileUtils.jsm", tempScope);
Components.utils.import("resource://gre/modules/NetUtil.jsm", tempScope);
var FileUtils = tempScope.FileUtils;
var NetUtil = tempScope.NetUtil;
add_task(function* () {
let htmlFile = yield copy(TESTCASE_URI_HTML, "simple.html");
yield copy(TESTCASE_URI_CSS, "simple.css");
let uri = Services.io.newFileURI(htmlFile);
let filePath = uri.resolve("");
let { ui } = yield openStyleEditorForURL(filePath);
let editor = ui.editors[0];
yield editor.getSourceEditor();
info("Editing the style sheet.");
let dirty = editor.sourceEditor.once("dirty-change");
let beginCursor = {line: 0, ch: 0};
editor.sourceEditor.replaceText("DIRTY TEXT", beginCursor, beginCursor);
yield dirty;
is(editor.sourceEditor.isClean(), false, "Editor is dirty.");
ok(editor.summary.classList.contains("unsaved"),
"Star icon is present in the corresponding summary.");
info("Saving the changes.");
dirty = editor.sourceEditor.once("dirty-change");
editor.saveToFile(null, function (file) {
ok(file, "file should get saved directly when using a file:// URI");
});
yield dirty;
is(editor.sourceEditor.isClean(), true, "Editor is clean.");
ok(!editor.summary.classList.contains("unsaved"),
"Star icon is not present in the corresponding summary.");
});
function copy(srcChromeURL, destFileName) {
let deferred = defer();
let destFile = FileUtils.getFile("ProfD", [destFileName]);
write(read(srcChromeURL), destFile, deferred.resolve);
return deferred.promise;
}
function read(srcChromeURL) {
let scriptableStream = Cc["@mozilla.org/scriptableinputstream;1"]
.getService(Ci.nsIScriptableInputStream);
let channel = NetUtil.newChannel({
uri: srcChromeURL,
loadUsingSystemPrincipal: true
});
let input = channel.open2();
scriptableStream.init(input);
let data = "";
while (input.available()) {
data = data.concat(scriptableStream.read(input.available()));
}
scriptableStream.close();
input.close();
return data;
}
function write(data, file, callback) {
let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
.createInstance(Ci.nsIScriptableUnicodeConverter);
converter.charset = "UTF-8";
let istream = converter.convertToInputStream(data);
let ostream = FileUtils.openSafeFileOutputStream(file);
NetUtil.asyncCopy(istream, ostream, function (status) {
if (!Components.isSuccessCode(status)) {
info("Couldn't write to " + file.path);
return;
}
callback(file);
});
}
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test that 'Save' function works.
const TESTCASE_URI_HTML = TEST_BASE_HTTP + "simple.html";
const TESTCASE_URI_CSS = TEST_BASE_HTTP + "simple.css";
var tempScope = {};
Components.utils.import("resource://gre/modules/FileUtils.jsm", tempScope);
Components.utils.import("resource://gre/modules/NetUtil.jsm", tempScope);
var FileUtils = tempScope.FileUtils;
var NetUtil = tempScope.NetUtil;
add_task(function* () {
let htmlFile = yield copy(TESTCASE_URI_HTML, "simple.html");
const cssFile = await copy(TESTCASE_URI_CSS, "simple.css");
let uri = Services.io.newFileURI(htmlFile);
let filePath = uri.resolve("");
let { ui } = yield openStyleEditorForURL(filePath);
let editor = ui.editors[0];
yield editor.getSourceEditor();
is(
editor.savedFile,
null,
"savedFile should not be pre-populated from the source file"
);
info("Editing the style sheet.");
let dirty = editor.sourceEditor.once("dirty-change");
let beginCursor = {line: 0, ch: 0};
editor.sourceEditor.replaceText("DIRTY TEXT", beginCursor, beginCursor);
yield dirty;
is(editor.sourceEditor.isClean(), false, "Editor is dirty.");
ok(editor.summary.classList.contains("unsaved"),
"Star icon is present in the corresponding summary.");
info(
"Saving the changes with an explicit file (simulating a user-chosen save location)."
);
dirty = editor.sourceEditor.once("dirty-change");
editor.saveToFile(cssFile, function (file) {
ok(file, "file should get saved when explicitly passing a file");
});
yield dirty;
is(editor.sourceEditor.isClean(), true, "Editor is clean.");
ok(!editor.summary.classList.contains("unsaved"),
"Star icon is not present in the corresponding summary.");
is(
editor.savedFile?.path,
cssFile.path,
"savedFile should now be set on the editor"
);
});
function copy(srcChromeURL, destFileName) {
let deferred = defer();
let destFile = FileUtils.getFile("ProfD", [destFileName]);
write(read(srcChromeURL), destFile, deferred.resolve);
return deferred.promise;
}
function read(srcChromeURL) {
let scriptableStream = Cc["@mozilla.org/scriptableinputstream;1"]
.getService(Ci.nsIScriptableInputStream);
let channel = NetUtil.newChannel({
uri: srcChromeURL,
loadUsingSystemPrincipal: true
});
let input = channel.open2();
scriptableStream.init(input);
let data = "";
while (input.available()) {
data = data.concat(scriptableStream.read(input.available()));
}
scriptableStream.close();
input.close();
return data;
}
function write(data, file, callback) {
let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
.createInstance(Ci.nsIScriptableUnicodeConverter);
converter.charset = "UTF-8";
let istream = converter.convertToInputStream(data);
let ostream = FileUtils.openSafeFileOutputStream(file);
NetUtil.asyncCopy(istream, ostream, function (status) {
if (!Components.isSuccessCode(status)) {
info("Couldn't write to " + file.path);
return;
}
callback(file);
});
}
@@ -28,7 +28,10 @@ add_task(function* () {
let HTMLFile = yield copy(TESTCASE_URI_HTML, ["sourcemaps.html"]);
let CSSFile = yield copy(TESTCASE_URI_CSS,
["sourcemap-css", "sourcemaps.css"]);
yield copy(TESTCASE_URI_SCSS, ["sourcemap-sass", "sourcemaps.scss"]);
const SCSSFile = await copy(TESTCASE_URI_SCSS, [
"sourcemap-sass",
"sourcemaps.scss",
]);
yield copy(TESTCASE_URI_MAP, ["sourcemap-css", "sourcemaps.css.map"]);
yield copy(TESTCASE_URI_REG_CSS, ["simple.css"]);
@@ -59,7 +62,7 @@ add_task(function* () {
// Edit and save Sass in the editor. This will start off a file-watching
// process waiting for the CSS file to change.
yield editSCSS(editor);
yield editSCSS(SCSSFile, editor);
// We can't run Sass or another compiler, so we fake it by just
// directly changing the CSS file.
@@ -73,12 +76,12 @@ add_task(function* () {
is(color, "rgb(0, 0, 255)", "div is blue after saving file");
});
function editSCSS(editor) {
function editSCSS(SCSSFile, editor) {
let deferred = defer();
editor.sourceEditor.setText(CSS_TEXT);
editor.saveToFile(null, function (file) {
editor.saveToFile(SCSSFile, function (file) {
ok(file, "Scss file should be saved");
deferred.resolve();
});
+2 -1
View File
@@ -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
+1 -1
View File
@@ -196,7 +196,7 @@ public:
{
MOZ_ASSERT(!NS_IsMainThread());
int32_t written = PR_Write(mFD, mData, mLength);
int32_t written = mLength < INT32_MAX ? PR_Write(mFD, mData, mLength) : -1;
if (NS_WARN_IF(written < 0 || uint32_t(written) != mLength)) {
return NS_DispatchToMainThread(
new ErrorPropagationRunnable(mBlobStorage, NS_ERROR_FAILURE));
+1 -1
View File
@@ -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))
+2 -2
View File
@@ -97,7 +97,7 @@ ToJSValue(JSContext* aCx,
return true;
}
// accept floating point types
// Accept floating point types
inline bool
ToJSValue(JSContext* aCx,
float aArgument,
@@ -106,7 +106,7 @@ ToJSValue(JSContext* aCx,
// Make sure we're called in a compartment
MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
aValue.setNumber(aArgument);
aValue.set(JS_NumberValue(double(aArgument)));
return true;
}
+46 -30
View File
@@ -39,6 +39,44 @@ WebGLTransformFeedback::Delete()
////////////////////////////////////////
// Validation helper for beginning/resuming the TF and computing the
// vertex capacity.
bool
WebGLTransformFeedback::PrepareTransformFeedback() {
const auto& prog = mContext->mCurrentProgram;
if (!prog ||
!prog->IsLinked() ||
!prog->LinkInfo()->componentsPerTFVert.size()) {
mContext->ErrorInvalidOperation("Current program not valid for transform feedback.");
return false;
}
const auto& linkInfo = prog->LinkInfo();
const auto& componentsPerTFVert = linkInfo->componentsPerTFVert;
mActive_VertCapacity = 0;
size_t minVertCapacity = SIZE_MAX;
for (size_t i = 0; i < componentsPerTFVert.size(); i++) {
const auto& indexedBinding = mIndexedBindings[i];
const auto& componentsPerVert = componentsPerTFVert[i];
const auto& buffer = indexedBinding.mBufferBinding;
if (!buffer) {
mContext->ErrorInvalidOperation("No buffer attached to required transform feedback index %u.",
(uint32_t)i);
return false;
}
const size_t vertCapacity = buffer->ByteLength() / 4 / componentsPerVert;
minVertCapacity = std::min(minVertCapacity, vertCapacity);
}
mActive_VertCapacity = minVertCapacity;
return true;
}
void
WebGLTransformFeedback::BeginTransformFeedback(GLenum primMode)
{
@@ -59,37 +97,10 @@ WebGLTransformFeedback::BeginTransformFeedback(GLenum primMode)
return;
}
const auto& prog = mContext->mCurrentProgram;
if (!prog ||
!prog->IsLinked() ||
!prog->LinkInfo()->componentsPerTFVert.size())
{
mContext->ErrorInvalidOperation("%s: Current program not valid for transform"
" feedback.",
funcName);
if (!PrepareTransformFeedback()) {
return;
}
const auto& linkInfo = prog->LinkInfo();
const auto& componentsPerTFVert = linkInfo->componentsPerTFVert;
size_t minVertCapacity = SIZE_MAX;
for (size_t i = 0; i < componentsPerTFVert.size(); i++) {
const auto& indexedBinding = mIndexedBindings[i];
const auto& componentsPerVert = componentsPerTFVert[i];
const auto& buffer = indexedBinding.mBufferBinding;
if (!buffer) {
mContext->ErrorInvalidOperation("%s: No buffer attached to required transform"
" feedback index %u.",
funcName, (uint32_t)i);
return;
}
const size_t vertCapacity = buffer->ByteLength() / 4 / componentsPerVert;
minVertCapacity = std::min(minVertCapacity, vertCapacity);
}
////
const auto& gl = mContext->gl;
@@ -101,10 +112,9 @@ WebGLTransformFeedback::BeginTransformFeedback(GLenum primMode)
mIsActive = true;
MOZ_ASSERT(!mIsPaused);
mActive_Program = prog;
mActive_Program = mContext->mCurrentProgram;
mActive_PrimMode = primMode;
mActive_VertPosition = 0;
mActive_VertCapacity = minVertCapacity;
////
@@ -173,6 +183,12 @@ WebGLTransformFeedback::ResumeTransformFeedback()
return;
}
// Re-run prepare in case some of the buffers have been modified
// while the TF was paused.
if (!PrepareTransformFeedback()) {
return;
}
////
const auto& gl = mContext->gl;
+1
View File
@@ -44,6 +44,7 @@ public:
WebGLTransformFeedback(WebGLContext* webgl, GLuint tf);
private:
~WebGLTransformFeedback();
bool PrepareTransformFeedback();
public:
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLTransformFeedback)
+2 -10
View File
@@ -876,20 +876,12 @@ HTMLImageElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
return HTMLImageElementBinding::Wrap(aCx, this, aGivenProto);
}
#ifdef DEBUG
nsIDOMHTMLFormElement*
HTMLImageElement::GetForm() const
{
return mForm;
}
#endif
void
HTMLImageElement::SetForm(nsIDOMHTMLFormElement* aForm)
{
NS_PRECONDITION(aForm, "Don't pass null here");
NS_ASSERTION(!mForm,
"We don't support switching from one non-null form to another.");
MOZ_ASSERT(!mForm && !HasFlag(ADDED_TO_FORM),
"We don't support switching from one non-null form to another.");
mForm = static_cast<HTMLFormElement*>(aForm);
}
+2 -3
View File
@@ -216,9 +216,8 @@ public:
SetHTMLAttr(nsGkAtoms::lowsrc, aLowsrc, aError);
}
#ifdef DEBUG
nsIDOMHTMLFormElement* GetForm() const;
#endif
HTMLFormElement* GetForm() const { return mForm; };
void SetForm(nsIDOMHTMLFormElement* aForm);
void ClearForm(bool aRemoveFromForm);
+5 -1
View File
@@ -18,6 +18,8 @@
#include "nsContentUtils.h"
#include "nsIContentSecurityPolicy.h"
#include "nsIURI.h"
#include "nsNetUtil.h"
#include "nsIProtocolHandler.h"
NS_IMPL_NS_NEW_HTML_ELEMENT(Shared)
@@ -186,6 +188,8 @@ SetBaseURIUsingFirstBaseWithHref(nsIDocument* aDocument, nsIContent* aMustMatch)
newBaseURI = nullptr;
}
if (csp && newBaseURI) {
bool isLocalResource = false;
rv = NS_URIChainHasFlags(newBaseURI, nsIProtocolHandler::URI_IS_LOCAL_RESOURCE, &isLocalResource);
// base-uri is only enforced if explicitly defined in the
// policy - do *not* consult default-src, see:
// http://www.w3.org/TR/CSP2/#directive-default-src
@@ -193,7 +197,7 @@ SetBaseURIUsingFirstBaseWithHref(nsIDocument* aDocument, nsIContent* aMustMatch)
rv = csp->Permits(newBaseURI, nsIContentSecurityPolicy::BASE_URI_DIRECTIVE,
true /* aSpecific */, true /* aSendViolationReports */,
&cspPermitsBaseURI);
if (NS_FAILED(rv) || !cspPermitsBaseURI) {
if ((NS_FAILED(rv) || !cspPermitsBaseURI) && !isLocalResource) {
newBaseURI = nullptr;
}
}
+11 -4
View File
@@ -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);
}
}
}
@@ -1824,8 +1831,8 @@ void
nsGenericHTMLFormElement::SetForm(nsIDOMHTMLFormElement* aForm)
{
NS_PRECONDITION(aForm, "Don't pass null here");
NS_ASSERTION(!mForm,
"We don't support switching from one non-null form to another.");
MOZ_ASSERT(!mForm && !HasFlag(ADDED_TO_FORM),
"We don't support switching from one non-null form to another.");
// keep a *weak* ref to the form here
mForm = static_cast<HTMLFormElement*>(aForm);
+1 -1
View File
@@ -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
+2 -1
View File
@@ -367,12 +367,13 @@ public:
{
}
static const uint32_t MIN_RATE = 8000;
static const uint32_t MAX_RATE = 640000;
bool IsValid() const override
{
return mChannels > 0 && mChannels <= MAX_AUDIO_CHANNELS
&& mRate > 0 && mRate <= MAX_RATE;
&& mRate >= MIN_RATE && mRate <= MAX_RATE;
}
AudioInfo* GetAsAudioInfo() override
+6
View File
@@ -179,12 +179,18 @@ IsValidVideoRegion(const nsIntSize& aFrame, const nsIntRect& aPicture,
aFrame.height <= PlanarYCbCrImage::MAX_DIMENSION &&
aFrame.width * aFrame.height <= MAX_VIDEO_WIDTH * MAX_VIDEO_HEIGHT &&
aFrame.width * aFrame.height != 0 &&
aPicture.width > 0 &&
aPicture.width <= PlanarYCbCrImage::MAX_DIMENSION &&
aPicture.x >= 0 &&
aPicture.x < PlanarYCbCrImage::MAX_DIMENSION &&
aPicture.x + aPicture.width < PlanarYCbCrImage::MAX_DIMENSION &&
aPicture.XMost() <= aFrame.width &&
aPicture.height > 0 &&
aPicture.height <= PlanarYCbCrImage::MAX_DIMENSION &&
aPicture.y >= 0 &&
aPicture.y < PlanarYCbCrImage::MAX_DIMENSION &&
aPicture.y + aPicture.height < PlanarYCbCrImage::MAX_DIMENSION &&
aPicture.YMost() <= aFrame.height &&
aPicture.width * aPicture.height <= MAX_VIDEO_WIDTH * MAX_VIDEO_HEIGHT &&
aPicture.width * aPicture.height != 0 &&
aDisplay.width <= PlanarYCbCrImage::MAX_DIMENSION &&
+1 -1
View File
@@ -439,7 +439,7 @@ private:
Maybe<size_t> mInitOffset;
Maybe<size_t> mMediaOffset;
bool mValid = true;
char mLastInvalidBox[5];
char mLastInvalidBox[5]{};
};
public:
+1 -1
View File
@@ -26,7 +26,7 @@ ThreadSharedFloatArrayBufferList::Create(uint32_t aChannelCount,
new ThreadSharedFloatArrayBufferList(aChannelCount);
for (uint32_t i = 0; i < aChannelCount; ++i) {
float* channelData = js_pod_malloc<float>(aLength);
float* channelData = js_pod_calloc<float>(aLength);
if (!channelData) {
return nullptr;
}
+2 -2
View File
@@ -40,8 +40,8 @@ public:
}
/**
* Create with buffers suitable for transfer to
* JS_NewArrayBufferWithContents(). The buffer contents are uninitialized
* and so should be set using GetDataForWrite().
* JS_NewArrayBufferWithContents(). The buffer contents are
* zero-initialized; callers should set them using GetDataForWrite().
*/
static already_AddRefed<ThreadSharedFloatArrayBufferList>
Create(uint32_t aChannelCount, size_t aLength, const mozilla::fallible_t&);
+14 -5
View File
@@ -20,6 +20,7 @@
#include "WebMBufferedParser.h"
#include "gfx2DGlue.h"
#include "mozilla/Atomics.h"
#include "mozilla/CheckedInt.h"
#include "mozilla/EndianUtils.h"
#include "mozilla/Maybe.h"
#include "mozilla/SharedThreadPool.h"
@@ -352,19 +353,27 @@ WebMDemuxer::ReadMetadata()
mInfo.mVideo.mExtraData = new MediaByteBuffer(length);
mInfo.mVideo.mExtraData->AppendElements(data, length);
break;
}
}
default:
NS_WARNING("Unknown WebM video codec");
return NS_ERROR_FAILURE;
}
// Picture region, taking into account cropping, before scaling
// to the display size.
unsigned int cropH = params.crop_right + params.crop_left;
unsigned int cropV = params.crop_bottom + params.crop_top;
CheckedInt<uint32_t> cropH = CheckedInt<uint32_t>(params.crop_left) + params.crop_right;
CheckedInt<uint32_t> cropV = CheckedInt<uint32_t>(params.crop_top) + params.crop_bottom;
if (!cropH.isValid() || !cropV.isValid() ||
cropH.value() >= params.width || cropV.value() >= params.height) {
WEBM_DEBUG("Invalid crop values left: {} right: {} top: {} bottom: {}",
params.crop_left, params.crop_right, params.crop_top,
params.crop_bottom);
// Ignore invalid crop parameters.
continue;
}
nsIntRect pictureRect(params.crop_left,
params.crop_top,
params.width - cropH,
params.height - cropV);
params.width - cropH.value(),
params.height - cropV.value());
// If the cropping data appears invalid then use the frame data
if (pictureRect.width <= 0 ||
+37 -14
View File
@@ -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();
}
+3 -1
View File
@@ -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)
+7
View File
@@ -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;
}
+5 -3
View File
@@ -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']
+14 -5
View File
@@ -1789,17 +1789,26 @@ URL::IsValidURL(const GlobalObject& aGlobal, const nsAString& aURL,
return URLWorker::IsValidURL(aGlobal, aURL, aRv);
}
bool
URL::CanParse(const GlobalObject& aGlobal, const nsAString& aURL,
const Optional<nsAString>& aBase) {
already_AddRefed<URL>
URL::Parse(const GlobalObject& aGlobal, const nsAString& aURL,
const Optional<nsAString>& aBase)
{
ErrorResult rv;
RefPtr<URL> parsed = URL::Constructor(aGlobal, aURL, aBase, rv);
if (rv.Failed() || !parsed) {
rv.SuppressException();
return false;
return nullptr;
}
return true;
return parsed.forget();
}
bool
URL::CanParse(const GlobalObject& aGlobal, const nsAString& aURL,
const Optional<nsAString>& aBase)
{
RefPtr<URL> parsed = URL::Parse(aGlobal, aURL, aBase);
return !!parsed;
}
already_AddRefed<URLSearchParams>
+4
View File
@@ -88,6 +88,10 @@ public:
IsValidURL(const GlobalObject& aGlobal, const nsAString& aURL,
ErrorResult& aRv);
static already_AddRefed<URL>
Parse(const GlobalObject& aGlobal, const nsAString& aURL,
const Optional<nsAString>& aBase);
static bool
CanParse(const GlobalObject& aGlobal, const nsAString& aURL,
const Optional<nsAString>& aBase);
+28
View File
@@ -448,6 +448,34 @@
!URL.canParse("/static/client/runtime.js", "mailto:test@example.com"),
"URL.canParse rejects root-relative input against opaque mailto: base",
);
ok("parse" in URL, "URL.parse exists");
is(URL.parse.length, 1, "URL.parse has one required argument");
var parsed = URL.parse("/static/client/runtime.js", "x:/");
ok(parsed instanceof URL, "URL.parse returns a URL object on success");
is(parsed.href, "x:/static/client/runtime.js", "URL.parse resolves against a base");
is(URL.parse("/static/client/runtime.js"), null, "URL.parse returns null for invalid input");
is(
URL.parse("/static/client/runtime.js", "mailto:test@example.com"),
null,
"URL.parse returns null for an invalid base/input combination",
);
var conversionOrder = [];
parsed = URL.parse(
{ toString: function() { conversionOrder.push("url"); return "child"; } },
{ toString: function() { conversionOrder.push("base"); return "https://example.com/root/"; } },
);
is(conversionOrder.join(","), "url,base", "URL.parse converts its arguments in order");
is(parsed.href, "https://example.com/root/child", "URL.parse uses converted arguments");
var sentinel = {};
var thrown;
try {
URL.parse({ toString: function() { throw sentinel; } });
} catch (e) {
thrown = e;
}
is(thrown, sentinel, "URL.parse propagates argument conversion exceptions");
SimpleTest.doesThrow(() => {
new URL("/static/client/runtime.js", "mailto:test@example.com");
}, "constructor rejects root-relative input against opaque mailto: base");
+58
View File
@@ -301,6 +301,64 @@ onmessage = function () {
!URL.canParse("/static/client/runtime.js", "mailto:test@example.com"),
"URL.canParse rejects root-relative input against opaque mailto: base",
);
ok("parse" in URL, "URL.parse exists");
is(URL.parse.length, 1, "URL.parse has one required argument");
let parsed = URL.parse("/static/client/runtime.js", "x:/");
ok(parsed instanceof URL, "URL.parse returns a URL object on success");
is(
parsed.href,
"x:/static/client/runtime.js",
"URL.parse resolves against a base",
);
is(
URL.parse("/static/client/runtime.js"),
null,
"URL.parse returns null for invalid input",
);
is(
URL.parse("/static/client/runtime.js", "mailto:test@example.com"),
null,
"URL.parse returns null for an invalid base/input combination",
);
const conversionOrder = [];
parsed = URL.parse(
{
toString() {
conversionOrder.push("url");
return "child";
},
},
{
toString() {
conversionOrder.push("base");
return "https://example.com/root/";
},
},
);
is(
conversionOrder.join(","),
"url,base",
"URL.parse converts its arguments in order",
);
is(
parsed.href,
"https://example.com/root/child",
"URL.parse uses converted arguments",
);
const sentinel = {};
let thrown;
try {
URL.parse({
toString() {
throw sentinel;
},
});
} catch (e) {
thrown = e;
}
is(thrown, sentinel, "URL.parse propagates argument conversion exceptions");
let mailtoRelativeFailed = false;
try {
new URL("/static/client/runtime.js", "mailto:test@example.com");
+2
View File
@@ -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"]
+1 -2
View File
@@ -34,7 +34,6 @@ interface Element : Node {
[SameObject]
readonly attribute NamedNodeMap attributes;
[Pure]
sequence<DOMString> getAttributeNames();
[Pure]
DOMString? getAttribute(DOMString name);
@@ -159,7 +158,7 @@ interface Element : Node {
* this property returns an object with computed values for grid
* tracks and lines.
*/
[ChromeOnly, Pure]
[ChromeOnly]
sequence<Grid> getGridFragments();
};
+1 -1
View File
@@ -23,7 +23,7 @@ interface HTMLElement : Element {
[CEReactions, SetterThrows, Pure]
attribute DOMString dir;
[CEReactions, GetterThrows, Pure]
[CEReactions, GetterThrows]
attribute [TreatNullAs=EmptyString] DOMString innerText;
// user interaction
+1 -1
View File
@@ -51,7 +51,7 @@ interface HTMLInputElement : HTMLElement {
attribute boolean formNoValidate;
[CEReactions, Pure, SetterThrows]
attribute DOMString formTarget;
[CEReactions, Pure, SetterThrows]
[CEReactions, SetterThrows]
attribute unsigned long height;
[Pure]
attribute boolean indeterminate;
+1
View File
@@ -23,6 +23,7 @@ interface URL {
[Throws]
stringifier;
static URL? parse(USVString url, optional USVString base);
static boolean canParse(USVString url, optional USVString base);
[Throws]
+10
View File
@@ -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");
+1 -1
View File
@@ -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)
{
+1 -1
View File
@@ -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);
+120 -105
View File
@@ -805,6 +805,10 @@ cairo_cff_font_read_cid_fontdict (cairo_cff_font_t *font, unsigned char *ptr)
}
operand = decode_integer (operand, &size);
decode_integer (operand, &offset);
if (unlikely (offset < 0 || (unsigned long)offset > font->data_length)) {
status = CAIRO_INT_STATUS_UNSUPPORTED;
goto fail;
}
status = cff_dict_init (&font->fd_private_dict[i]);
if (unlikely (status))
goto fail;
@@ -866,6 +870,8 @@ cairo_cff_font_read_top_dict (cairo_cff_font_t *font)
operand = cff_dict_get_operands (font->top_dict, CHARSTRINGS_OP, &size);
decode_integer (operand, &offset);
p = font->data + offset;
if (unlikely (p < font->data || p > font->data_end))
return CAIRO_INT_STATUS_UNSUPPORTED;
status = cff_index_read (&font->charstrings_index, &p, font->data_end);
if (unlikely (status))
goto fail;
@@ -874,49 +880,58 @@ cairo_cff_font_read_top_dict (cairo_cff_font_t *font)
if (font->is_cid) {
operand = cff_dict_get_operands (font->top_dict, FDSELECT_OP, &size);
decode_integer (operand, &offset);
status = cairo_cff_font_read_fdselect (font, font->data + offset);
if (unlikely (status))
goto fail;
p = font->data + offset;
if (unlikely (p < font->data || p > font->data_end))
return CAIRO_INT_STATUS_UNSUPPORTED;
status = cairo_cff_font_read_fdselect (font, p);
if (unlikely (status))
goto fail;
operand = cff_dict_get_operands (font->top_dict, FDARRAY_OP, &size);
decode_integer (operand, &offset);
status = cairo_cff_font_read_cid_fontdict (font, font->data + offset);
if (unlikely (status))
goto fail;
p = font->data + offset;
if (unlikely (p < font->data || p > font->data_end))
return CAIRO_INT_STATUS_UNSUPPORTED;
status = cairo_cff_font_read_cid_fontdict (font, p);
if (unlikely (status))
goto fail;
} else {
operand = cff_dict_get_operands (font->top_dict, PRIVATE_OP, &size);
operand = decode_integer (operand, &size);
decode_integer (operand, &offset);
p = font->data + offset;
if (unlikely (p < font->data || p > font->data_end))
return CAIRO_INT_STATUS_UNSUPPORTED;
status = cairo_cff_font_read_private_dict (font,
font->private_dict,
&font->local_sub_index,
font->data + offset,
size);
if (unlikely (status))
goto fail;
&font->local_sub_index,
p,
size);
if (unlikely (status))
goto fail;
}
/* Use maximum sized encoding to reserve space for later modification. */
end_buf = encode_integer_max (buf, 0);
status = cff_dict_set_operands (font->top_dict,
CHARSTRINGS_OP, buf, end_buf - buf);
CHARSTRINGS_OP, buf, end_buf - buf);
if (unlikely (status))
goto fail;
goto fail;
status = cff_dict_set_operands (font->top_dict,
FDSELECT_OP, buf, end_buf - buf);
FDSELECT_OP, buf, end_buf - buf);
if (unlikely (status))
goto fail;
goto fail;
status = cff_dict_set_operands (font->top_dict,
FDARRAY_OP, buf, end_buf - buf);
FDARRAY_OP, buf, end_buf - buf);
if (unlikely (status))
goto fail;
goto fail;
status = cff_dict_set_operands (font->top_dict,
CHARSET_OP, buf, end_buf - buf);
CHARSET_OP, buf, end_buf - buf);
if (unlikely (status))
goto fail;
goto fail;
cff_dict_remove (font->top_dict, ENCODING_OP);
cff_dict_remove (font->top_dict, PRIVATE_OP);
@@ -985,26 +1000,26 @@ cairo_cff_font_set_ros_strings (cairo_cff_font_t *font)
(unsigned char *)registry,
strlen(registry));
if (unlikely (status))
return status;
return status;
sid2 = NUM_STD_STRINGS + _cairo_array_num_elements (&font->strings_subset_index);
status = cff_index_append_copy (&font->strings_subset_index,
(unsigned char *)ordering,
strlen(ordering));
strlen(ordering));
if (unlikely (status))
return status;
return status;
p = encode_integer (buf, sid1);
p = encode_integer (p, sid2);
p = encode_integer (p, 0);
status = cff_dict_set_operands (font->top_dict, ROS_OP, buf, p - buf);
if (unlikely (status))
return status;
return status;
p = encode_integer (buf, font->scaled_font_subset->num_glyphs);
status = cff_dict_set_operands (font->top_dict, CIDCOUNT_OP, buf, p - buf);
if (unlikely (status))
return status;
return status;
return CAIRO_STATUS_SUCCESS;
}
@@ -1038,7 +1053,7 @@ cairo_cff_font_subset_dict_string(cairo_cff_font_t *font,
p = encode_integer (buf, sid);
status = cff_dict_set_operands (dict, operator, buf, p - buf);
if (unlikely (status))
return status;
return status;
return CAIRO_STATUS_SUCCESS;
}
@@ -1101,19 +1116,19 @@ cairo_cff_font_subset_fontdict (cairo_cff_font_t *font)
font->fdselect_subset = calloc (font->scaled_font_subset->num_glyphs,
sizeof (int));
if (unlikely (font->fdselect_subset == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
font->fd_subset_map = calloc (font->num_fontdicts, sizeof (int));
if (unlikely (font->fd_subset_map == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
font->private_dict_offset = calloc (font->num_fontdicts, sizeof (int));
if (unlikely (font->private_dict_offset == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
reverse_map = calloc (font->num_fontdicts, sizeof (int));
if (unlikely (reverse_map == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
for (i = 0; i < font->num_fontdicts; i++)
reverse_map[i] = -1;
@@ -1143,22 +1158,22 @@ cairo_cff_font_create_cid_fontdict (cairo_cff_font_t *font)
font->num_fontdicts = 1;
font->fd_dict = malloc (sizeof (cairo_hash_table_t *));
if (unlikely (font->fd_dict == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
if (cff_dict_init (&font->fd_dict[0])) {
free (font->fd_dict);
font->fd_dict = NULL;
font->num_fontdicts = 0;
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
free (font->fd_dict);
font->fd_dict = NULL;
font->num_fontdicts = 0;
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
font->fd_subset_map = malloc (sizeof (int));
if (unlikely (font->fd_subset_map == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
font->private_dict_offset = malloc (sizeof (int));
if (unlikely (font->private_dict_offset == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
font->fd_subset_map[0] = 0;
font->num_subset_fontdicts = 1;
@@ -1169,7 +1184,7 @@ cairo_cff_font_create_cid_fontdict (cairo_cff_font_t *font)
end_buf = encode_integer_max (end_buf, 0);
status = cff_dict_set_operands (font->fd_dict[0], PRIVATE_OP, buf, end_buf - buf);
if (unlikely (status))
return status;
return status;
return CAIRO_STATUS_SUCCESS;
}
@@ -1208,7 +1223,7 @@ cairo_cff_font_subset_font (cairo_cff_font_t *font)
status = cairo_cff_font_set_ros_strings (font);
if (unlikely (status))
return status;
return status;
status = cairo_cff_font_subset_charstrings (font);
if (unlikely (status))
@@ -1219,7 +1234,7 @@ cairo_cff_font_subset_font (cairo_cff_font_t *font)
else
status = cairo_cff_font_create_cid_fontdict (font);
if (unlikely (status))
return status;
return status;
status = cairo_cff_font_subset_strings (font);
if (unlikely (status))
@@ -1271,7 +1286,7 @@ cairo_cff_font_write_name (cairo_cff_font_t *font)
(unsigned char *) font->subset_font_name,
strlen(font->subset_font_name));
if (unlikely (status))
goto FAIL;
goto FAIL;
status = cff_index_write (&index, &font->output);
if (unlikely (status))
@@ -1464,9 +1479,9 @@ cairo_cff_font_write_cid_fontdict (cairo_cff_font_t *font)
if (unlikely (status))
return status;
offset_array_ptr = (uint32_t *) _cairo_array_index (&font->output, offset_array);
offset_array_ptr = (uint32_t *) _cairo_array_index (&font->output, offset_array);
*offset_array_ptr = cpu_to_be32(_cairo_array_num_elements (&font->output) - offset_base);
offset_array += sizeof(uint32_t);
offset_array += sizeof(uint32_t);
}
return CAIRO_STATUS_SUCCESS;
@@ -1566,15 +1581,15 @@ cairo_cff_font_write_cid_private_dict_and_local_sub (cairo_cff_font_t *font)
0,
font->fd_dict[0],
font->private_dict);
if (unlikely (status))
return status;
if (unlikely (status))
return status;
status = cairo_cff_font_write_local_sub (font,
0,
font->private_dict,
&font->local_sub_index);
if (unlikely (status))
return status;
if (unlikely (status))
return status;
}
return CAIRO_STATUS_SUCCESS;
@@ -1698,7 +1713,7 @@ _cairo_cff_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
backend = scaled_font_subset->scaled_font->backend;
if (!backend->load_truetype_table)
return CAIRO_INT_STATUS_UNSUPPORTED;
return CAIRO_INT_STATUS_UNSUPPORTED;
data_length = 0;
status = backend->load_truetype_table( scaled_font_subset->scaled_font,
@@ -1736,12 +1751,12 @@ _cairo_cff_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
_cairo_array_init (&font->output, sizeof (char));
status = _cairo_array_grow_by (&font->output, 4096);
if (unlikely (status))
goto fail2;
goto fail2;
font->subset_font_name = strdup (subset_name);
if (unlikely (font->subset_font_name == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail2;
goto fail2;
}
font->x_min = (int16_t) be16_to_cpu (head.x_min);
font->y_min = (int16_t) be16_to_cpu (head.y_min);
@@ -1755,18 +1770,18 @@ _cairo_cff_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
font->font_name = NULL;
status = _cairo_truetype_read_font_name (scaled_font_subset->scaled_font,
&font->ps_name,
&font->font_name);
&font->ps_name,
&font->font_name);
if (_cairo_status_is_error (status))
goto fail3;
goto fail3;
/* If the PS name is not found, create a CairoFont-x-y name. */
if (font->ps_name == NULL) {
font->ps_name = malloc (30);
if (unlikely (font->ps_name == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail3;
}
}
snprintf(font->ps_name, 30, "CairoFont-%u-%u",
scaled_font_subset->font_id,
@@ -1781,7 +1796,7 @@ _cairo_cff_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
status = cairo_cff_font_create_set_widths (font);
if (unlikely (status))
goto fail5;
goto fail5;
font->data_length = data_length;
font->data = malloc (data_length);
@@ -1799,11 +1814,11 @@ _cairo_cff_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
status = cff_dict_init (&font->top_dict);
if (unlikely (status))
goto fail6;
goto fail6;
status = cff_dict_init (&font->private_dict);
if (unlikely (status))
goto fail7;
goto fail7;
cff_index_init (&font->strings_index);
cff_index_init (&font->charstrings_index);
@@ -1831,7 +1846,7 @@ fail5:
free (font->widths);
fail4:
if (font->font_name)
free (font->font_name);
free (font->font_name);
fail3:
free (font->subset_font_name);
fail2:
@@ -1848,7 +1863,7 @@ cairo_cff_font_destroy (cairo_cff_font_t *font)
free (font->widths);
if (font->font_name)
free (font->font_name);
free (font->font_name);
free (font->ps_name);
free (font->subset_font_name);
_cairo_array_fini (&font->output);
@@ -1902,7 +1917,7 @@ cairo_cff_font_destroy (cairo_cff_font_t *font)
cairo_status_t
_cairo_cff_subset_init (cairo_cff_subset_t *cff_subset,
const char *subset_name,
const char *subset_name,
cairo_scaled_font_subset_t *font_subset)
{
cairo_cff_font_t *font = NULL; /* squelch bogus compiler warning */
@@ -1913,32 +1928,32 @@ _cairo_cff_subset_init (cairo_cff_subset_t *cff_subset,
status = _cairo_cff_font_create (font_subset, &font, subset_name);
if (unlikely (status))
return status;
return status;
status = cairo_cff_font_generate (font, &data, &length);
if (unlikely (status))
goto fail1;
goto fail1;
cff_subset->ps_name = strdup (font->ps_name);
if (unlikely (cff_subset->ps_name == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail1;
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail1;
}
if (font->font_name) {
cff_subset->font_name = strdup (font->font_name);
if (cff_subset->font_name == NULL) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail2;
}
cff_subset->font_name = strdup (font->font_name);
if (cff_subset->font_name == NULL) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail2;
}
} else {
cff_subset->font_name = NULL;
cff_subset->font_name = NULL;
}
cff_subset->widths = calloc (sizeof (double), font->scaled_font_subset->num_glyphs);
if (unlikely (cff_subset->widths == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail3;
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail3;
}
for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
cff_subset->widths[i] = (double)font->widths[i]/font->units_per_em;
@@ -1952,8 +1967,8 @@ _cairo_cff_subset_init (cairo_cff_subset_t *cff_subset,
cff_subset->data = malloc (length);
if (unlikely (cff_subset->data == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail4;
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail4;
}
memcpy (cff_subset->data, data, length);
@@ -1967,7 +1982,7 @@ _cairo_cff_subset_init (cairo_cff_subset_t *cff_subset,
free (cff_subset->widths);
fail3:
if (cff_subset->font_name)
free (cff_subset->font_name);
free (cff_subset->font_name);
fail2:
free (cff_subset->ps_name);
fail1:
@@ -1981,7 +1996,7 @@ _cairo_cff_subset_fini (cairo_cff_subset_t *subset)
{
free (subset->ps_name);
if (subset->font_name)
free (subset->font_name);
free (subset->font_name);
free (subset->widths);
free (subset->data);
}
@@ -1996,7 +2011,7 @@ _cairo_cff_font_fallback_create (cairo_scaled_font_subset_t *scaled_font_subset
font = calloc (1, sizeof (cairo_cff_font_t));
if (unlikely (font == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
font->backend = NULL;
font->scaled_font_subset = scaled_font_subset;
@@ -2004,18 +2019,18 @@ _cairo_cff_font_fallback_create (cairo_scaled_font_subset_t *scaled_font_subset
_cairo_array_init (&font->output, sizeof (char));
status = _cairo_array_grow_by (&font->output, 4096);
if (unlikely (status))
goto fail1;
goto fail1;
font->subset_font_name = strdup (subset_name);
if (unlikely (font->subset_font_name == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail1;
goto fail1;
}
font->ps_name = strdup (subset_name);
if (unlikely (font->ps_name == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail2;
goto fail2;
}
font->font_name = NULL;
@@ -2038,11 +2053,11 @@ _cairo_cff_font_fallback_create (cairo_scaled_font_subset_t *scaled_font_subset
status = cff_dict_init (&font->top_dict);
if (unlikely (status))
goto fail4;
goto fail4;
status = cff_dict_init (&font->private_dict);
if (unlikely (status))
goto fail5;
goto fail5;
cff_index_init (&font->strings_index);
cff_index_init (&font->charstrings_index);
@@ -2068,7 +2083,7 @@ fail4:
free (font->widths);
fail3:
if (font->font_name)
free (font->font_name);
free (font->font_name);
free (font->ps_name);
fail2:
free (font->subset_font_name);
@@ -2105,39 +2120,39 @@ cairo_cff_font_fallback_generate (cairo_cff_font_t *font,
end_buf = encode_integer (end_buf, type2_subset->x_max);
end_buf = encode_integer (end_buf, type2_subset->y_max);
status = cff_dict_set_operands (font->top_dict,
FONTBBOX_OP, buf, end_buf - buf);
FONTBBOX_OP, buf, end_buf - buf);
if (unlikely (status))
return status;
return status;
end_buf = encode_integer_max (buf, 0);
status = cff_dict_set_operands (font->top_dict,
CHARSTRINGS_OP, buf, end_buf - buf);
CHARSTRINGS_OP, buf, end_buf - buf);
if (unlikely (status))
return status;
return status;
status = cff_dict_set_operands (font->top_dict,
FDSELECT_OP, buf, end_buf - buf);
FDSELECT_OP, buf, end_buf - buf);
if (unlikely (status))
return status;
return status;
status = cff_dict_set_operands (font->top_dict,
FDARRAY_OP, buf, end_buf - buf);
FDARRAY_OP, buf, end_buf - buf);
if (unlikely (status))
return status;
return status;
status = cff_dict_set_operands (font->top_dict,
CHARSET_OP, buf, end_buf - buf);
CHARSET_OP, buf, end_buf - buf);
if (unlikely (status))
return status;
return status;
status = cairo_cff_font_set_ros_strings (font);
if (unlikely (status))
return status;
return status;
/* Create CID FD dictionary */
status = cairo_cff_font_create_cid_fontdict (font);
if (unlikely (status))
return status;
return status;
/* Create charstrings */
for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
@@ -2163,7 +2178,7 @@ cairo_cff_font_fallback_generate (cairo_cff_font_t *font,
cairo_status_t
_cairo_cff_fallback_init (cairo_cff_subset_t *cff_subset,
const char *subset_name,
const char *subset_name,
cairo_scaled_font_subset_t *font_subset)
{
cairo_cff_font_t *font = NULL; /* squelch bogus compiler warning */
@@ -2175,27 +2190,27 @@ _cairo_cff_fallback_init (cairo_cff_subset_t *cff_subset,
status = _cairo_cff_font_fallback_create (font_subset, &font, subset_name);
if (unlikely (status))
return status;
return status;
status = _cairo_type2_charstrings_init (&type2_subset, font_subset);
if (unlikely (status))
goto fail1;
goto fail1;
status = cairo_cff_font_fallback_generate (font, &type2_subset, &data, &length);
if (unlikely (status))
goto fail2;
goto fail2;
cff_subset->font_name = NULL;
cff_subset->ps_name = strdup (font->ps_name);
if (unlikely (cff_subset->ps_name == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail2;
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail2;
}
cff_subset->widths = calloc (sizeof (double), font->scaled_font_subset->num_glyphs);
if (unlikely (cff_subset->widths == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail3;
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail3;
}
for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
@@ -2210,8 +2225,8 @@ _cairo_cff_fallback_init (cairo_cff_subset_t *cff_subset,
cff_subset->data = malloc (length);
if (unlikely (cff_subset->data == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail4;
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail4;
}
memcpy (cff_subset->data, data, length);
+58 -15
View File
@@ -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
+6 -1
View File
@@ -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
};
+6 -4
View File
@@ -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
+4
View File
@@ -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) {
+6
View File
@@ -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;
+21
View File
@@ -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
}
+3 -2
View File
@@ -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;)
};
}
+33 -1
View File
@@ -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);
+1 -1
View File
@@ -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
+21
View File
@@ -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 {
+14 -1
View File
@@ -336,7 +336,20 @@ gfxGraphiteShaper::SetGlyphsFromSegment(DrawTarget *aDrawTarget,
// not a one-to-one mapping with simple metrics: use DetailedGlyph
AutoTArray<gfxShapedText::DetailedGlyph,8> details;
float clusterLoc;
for (uint32_t j = c.baseGlyph; j < c.baseGlyph + c.nGlyphs; ++j) {
uint32_t glyph_start = c.baseGlyph;
uint32_t glyph_end = glyph_start + c.nGlyphs;
if (glyph_end < glyph_start) {
return NS_ERROR_ILLEGAL_VALUE;
}
if (glyph_end - glyph_start > 0xFFFF) {
return NS_ERROR_ILLEGAL_VALUE;
}
if (!details.SetCapacity(glyph_end - glyph_start, fallible)) {
return NS_ERROR_OUT_OF_MEMORY;
}
for (uint32_t j = glyph_start; j < glyph_end; ++j) {
gfxShapedText::DetailedGlyph* d = details.AppendElement();
d->mGlyphID = gids[j];
d->mYOffset = roundY ? NSToIntRound(-yLocs[j]) * dev2appUnits :
+15 -7
View File
@@ -231,11 +231,13 @@ gfxTextRun::ComputeLigatureData(Range aPartRange,
LigatureData result;
const CompressedGlyph *charGlyphs = mCharacterGlyphs;
uint32_t i;
for (i = aPartRange.start; !charGlyphs[i].IsLigatureGroupStart(); --i) {
NS_ASSERTION(i > 0, "Ligature at the start of the run??");
uint32_t i = aPartRange.start;
while (i && !charGlyphs[i].IsLigatureGroupStart()) {
--i;
}
NS_ASSERTION(charGlyphs[i].IsLigatureGroupStart(), "Ligature at run start?");
result.mRange.start = i;
for (i = aPartRange.start + 1;
i < GetLength() && !charGlyphs[i].IsLigatureGroupStart(); ++i) {
}
@@ -1704,21 +1706,27 @@ gfxFontGroup::GetFontAt(int32_t i, uint32_t aCh)
RefPtr<gfxFont> font = ff.Font();
if (!font) {
gfxFontEntry* fe = mFonts[i].FontEntry();
gfxCharacterMap* unicodeRangeMap = nullptr;
RefPtr<gfxFontEntry> fe = ff.FontEntry();
if (!fe) {
return nullptr;
}
RefPtr<gfxCharacterMap> unicodeRangeMap;
if (fe->mIsUserFontContainer) {
gfxUserFontEntry* ufe = static_cast<gfxUserFontEntry*>(fe);
// This raw pointer is OK because fe holds a strong ref to the object.
gfxUserFontEntry* ufe = static_cast<gfxUserFontEntry*>(fe.get());
if (ufe->LoadState() == gfxUserFontEntry::STATUS_NOT_LOADED &&
ufe->CharacterInUnicodeRange(aCh) &&
!FontLoadingForFamily(ff.Family(), aCh)) {
ufe->Load();
ff.CheckState(mSkipDrawing);
}
unicodeRangeMap = ufe->GetUnicodeRangeMap();
// Update fe to refer to the actual platform font entry, rather than the
// webfont wrapper. After this, we no longer have a strong ref to ufe.
fe = ufe->GetPlatformFontEntry();
if (!fe) {
return nullptr;
}
unicodeRangeMap = ufe->GetUnicodeRangeMap();
}
font = fe->FindOrMakeFont(&mStyle, mFonts[i].NeedsBold(),
unicodeRangeMap);
+7 -4
View File
@@ -1637,10 +1637,13 @@ RasterImage::NotifyDecodeComplete(const DecoderFinalStatus& aStatus,
if (!(aDecoderFlags & DecoderFlags::FIRST_FRAME_ONLY) &&
mHasBeenDecoded && mAnimationState) {
// We've finished a full decode of all animation frames and our AnimationState
// has been notified about them all, so let it know not to expect anymore.
mAnimationState->NotifyDecodeComplete();
mAnimationState->UpdateState(mAnimationFinished, this, mSize);
// If we've successfully finished a full decode of all animation frames
// then let our animation state know it's complete and to not to expect
// any more frames.
if (aStatus.mFinished && !aStatus.mHadError) {
mAnimationState->NotifyDecodeComplete();
mAnimationState->UpdateState(mAnimationFinished, this, mSize);
}
}
// Only act on errors if we have no usable frames from the decoder.
+6 -1
View File
@@ -8,8 +8,11 @@
#include "mozilla/CheckedInt.h"
#include "mozilla/TypeTraits.h"
#include <algorithm>
#include "jscntxt.h"
#include "builtin/SelfHostingDefines.h"
#include "irregexp/RegExpParser.h"
#include "jit/InlinableNatives.h"
#include "vm/RegExpStatics.h"
@@ -1754,7 +1757,9 @@ js::RegExpGetSubstitution(JSContext* cx, HandleArrayObject matchResult, HandleLi
// Step 6.
MOZ_ASSERT(position <= string->length());
uint32_t nCaptures = matchResultLength - 1;
// String substitutions can only reference $1 through $99.
uint32_t nCaptures = std::min<uint32_t>(matchResultLength - 1,
REGEXP_MAX_SUBSTITUTION_CAPTURES);
Rooted<CapturesVector> captures(cx, CapturesVector(cx));
if (!captures.reserve(nCaptures))
return false;
+9 -1
View File
@@ -463,6 +463,12 @@ function RegExpGetComplexReplacement(result, matched, S, position,
// Step 14.k.i (reordered).
_DefineDataProperty(captures, capturesLength++, matched);
// String substitutions can only reference $1 through $99. Keep getting and
// stringifying all captures because those operations are observable.
var storedCaptures = functionalReplace ?
nCaptures :
std_Math_min(nCaptures, REGEXP_MAX_SUBSTITUTION_CAPTURES);
// Step 14.g, 14.i, 14.i.iv.
for (var n = 1; n <= nCaptures; n++) {
// Step 14.i.i.
@@ -473,7 +479,9 @@ function RegExpGetComplexReplacement(result, matched, S, position,
capN = ToString(capN);
// Step 14.i.iii.
_DefineDataProperty(captures, capturesLength++, capN);
if (n <= storedCaptures) {
_DefineDataProperty(captures, capturesLength++, capN);
}
}
// Step 14.j.
+2
View File
@@ -79,6 +79,8 @@
#define REGEXP_FLAGS_SLOT 2
#define REGEXP_MAX_SUBSTITUTION_CAPTURES 99
#define REGEXP_IGNORECASE_FLAG 0x01
#define REGEXP_GLOBAL_FLAG 0x02
#define REGEXP_MULTILINE_FLAG 0x04
@@ -1,4 +1,3 @@
// |jit-test| --ion-sink=on
// Sink Algorithm should not move instruction into merge blocks
// which have no corresponding pc.
+3 -3
View File
@@ -2439,7 +2439,7 @@ static const VMFunction GetOrCreateModuleMetaObjectInfo =
void
CodeGenerator::visitModuleMetadata(LModuleMetadata* lir)
{
pushArg(ImmPtr(lir->mir()->module()));
pushArg(ImmGCPtr(lir->mir()->module()));
callVM(GetOrCreateModuleMetaObjectInfo, lir);
}
@@ -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);
-2
View File
@@ -34,7 +34,6 @@ OptimizationInfo::initNormalOptimizationInfo()
rangeAnalysis_ = true;
reordering_ = true;
sincos_ = true;
sink_ = true;
registerAllocator_ = RegisterAllocator_Backtracking;
@@ -69,7 +68,6 @@ OptimizationInfo::initWasmOptimizationInfo()
eliminateRedundantChecks_ = false;
scalarReplacement_ = false; // wasm has no objects.
sincos_ = false;
sink_ = false;
}
uint32_t
-7
View File
@@ -86,9 +86,6 @@ class OptimizationInfo
// Toggles whether sincos is used.
bool sincos_;
// Toggles whether sink is used.
bool sink_;
// Describes which register allocator to use.
IonRegisterAllocator registerAllocator_;
@@ -194,10 +191,6 @@ class OptimizationInfo
return sincos_ && !JitOptions.disableSincos;
}
bool sinkEnabled() const {
return sink_ && !JitOptions.disableSink;
}
bool eaaEnabled() const {
return eaa_ && !JitOptions.disableEaa;
}
+3
View File
@@ -494,6 +494,9 @@ OnLeaveBaselineFrame(JSContext* cx, const JitFrameIterator& frame, jsbytecode* p
{
BaselineFrame* baselineFrame = frame.baselineFrame();
if (jit::DebugEpilogue(cx, baselineFrame, pc, frameOk)) {
if (!baselineFrame->hasReturnValue()) {
baselineFrame->setReturnValue(UndefinedValue());
}
rfe->kind = ResumeFromException::RESUME_FORCED_RETURN;
rfe->framePointer = frame.fp() - BaselineFrame::FramePointerOffset;
rfe->stackPointer = reinterpret_cast<uint8_t*>(baselineFrame);
-3
View File
@@ -130,9 +130,6 @@ DefaultJitOptions::DefaultJitOptions()
SET_DEFAULT(disableSincos, true);
#endif
// Toggles whether sink code motion is globally disabled.
SET_DEFAULT(disableSink, true);
// Whether functions are compiled immediately.
SET_DEFAULT(eagerCompilation, false);
-1
View File
@@ -63,7 +63,6 @@ struct DefaultJitOptions
bool disableCacheIR;
bool disableSharedStubs;
bool disableSincos;
bool disableSink;
bool eagerCompilation;
bool forceInlineCaches;
bool limitScriptSize;
-122
View File
@@ -44,9 +44,6 @@ CommonDominator(MBasicBlock* commonDominator, MBasicBlock* defBlock)
bool
Sink(MIRGenerator* mir, MIRGraph& graph)
{
TempAllocator& alloc = graph.alloc();
bool sinkEnabled = mir->optimizationInfo().sinkEnabled();
for (PostorderIterator block = graph.poBegin(); block != graph.poEnd(); block++) {
if (mir->shouldCancel("Sink"))
return false;
@@ -106,125 +103,6 @@ Sink(MIRGenerator* mir, MIRGraph& graph)
JitSpewDef(JitSpew_Sink, " No live uses, recover the instruction on bailout\n", ins);
continue;
}
// This guard is temporarly moved here as the above code deals with
// Dead Code elimination, which got moved into this Sink phase, as
// the Dead Code elimination used to move instructions with no-live
// uses to the bailout path.
if (!sinkEnabled)
continue;
// To move an effectful instruction, we would have to verify that the
// side-effect is not observed. In the mean time, we just inhibit
// this optimization on effectful instructions.
if (ins->isEffectful())
continue;
// If all the uses are under a loop, we might not want to work
// against LICM by moving everything back into the loop, but if the
// loop is it-self inside an if, then we still want to move the
// computation under this if statement.
while (block->loopDepth() < usesDominator->loopDepth()) {
MOZ_ASSERT(usesDominator != usesDominator->immediateDominator());
usesDominator = usesDominator->immediateDominator();
}
// Only move instructions if there is a branch between the dominator
// of the uses and the original instruction. This prevent moving the
// computation of the arguments into an inline function if there is
// no major win.
MBasicBlock* lastJoin = usesDominator;
while (*block != lastJoin && lastJoin->numPredecessors() == 1) {
MOZ_ASSERT(lastJoin != lastJoin->immediateDominator());
MBasicBlock* next = lastJoin->immediateDominator();
if (next->numSuccessors() > 1)
break;
lastJoin = next;
}
if (*block == lastJoin)
continue;
// Skip to the next instruction if we cannot find a common dominator
// for all the uses of this instruction, or if the common dominator
// correspond to the block of the current instruction.
if (!usesDominator || usesDominator == *block)
continue;
// Only instruction which can be recovered on bailout and which are
// sinkable can be moved into blocks which are below while filling
// the resume points with a clone which is recovered on bailout.
// If the instruction has live uses and if it is clonable, then we
// can clone the instruction for all non-dominated uses and move the
// instruction into the block which is dominating all live uses.
if (!ins->canClone())
continue;
// If the block is a split-edge block, which is created for folding
// test conditions, then the block has no resume point and has
// multiple predecessors. In such case, we cannot safely move
// bailing instruction to these blocks as we have no way to bailout.
if (!usesDominator->entryResumePoint() && usesDominator->numPredecessors() != 1)
continue;
JitSpewDef(JitSpew_Sink, " Can Clone & Recover, sink instruction\n", ins);
JitSpew(JitSpew_Sink, " into Block %u", usesDominator->id());
// Copy the arguments and clone the instruction.
MDefinitionVector operands(alloc);
for (size_t i = 0, end = ins->numOperands(); i < end; i++) {
if (!operands.append(ins->getOperand(i)))
return false;
}
MInstruction* clone = ins->clone(alloc, operands);
ins->block()->insertBefore(ins, clone);
clone->setRecoveredOnBailout();
// We should not update the producer of the entry resume point, as
// it cannot refer to any instruction within the basic block excepts
// for Phi nodes.
MResumePoint* entry = usesDominator->entryResumePoint();
// Replace the instruction by its clone in all the resume points /
// recovered-on-bailout instructions which are not in blocks which
// are dominated by the usesDominator block.
for (MUseIterator i(ins->usesBegin()), e(ins->usesEnd()); i != e; ) {
MUse* use = *i++;
MNode* consumer = use->consumer();
// If the consumer is a Phi, then we look for the index of the
// use to find the corresponding predecessor block, which is
// then used as the consumer block.
MBasicBlock* consumerBlock = consumer->block();
if (consumer->isDefinition() && consumer->toDefinition()->isPhi()) {
consumerBlock = consumerBlock->getPredecessor(
consumer->toDefinition()->toPhi()->indexOf(use));
}
// Keep the current instruction for all dominated uses, except
// for the entry resume point of the block in which the
// instruction would be moved into.
if (usesDominator->dominates(consumerBlock) &&
(!consumer->isResumePoint() || consumer->toResumePoint() != entry))
{
continue;
}
use->replaceProducer(clone);
}
// As we move this instruction in a different block, we should
// verify that we do not carry over a resume point which would refer
// to an outdated state of the control flow.
if (ins->resumePoint())
ins->clearResumePoint();
// Now, that all uses which are not dominated by usesDominator are
// using the cloned instruction, we can safely move the instruction
// into the usesDominator block.
MInstruction* at = usesDominator->safeInsertTop(nullptr, MBasicBlock::IgnoreRecover);
block->moveBefore(at, ins);
}
}
+5 -4
View File
@@ -312,12 +312,13 @@ cvt_s(SprintfState* ss, const char* s, int width, int prec, int flags)
s = generic_null_str(s);
// Limit string length by precision value
int slen = int(generic_strlen(s));
if (0 < prec && prec < slen)
slen = prec;
size_t slen = strnlen(s, size_t(prec));
if (slen > INT_MAX) {
return false;
}
// and away we go
return fill2(ss, s, slen, width, flags);
return fill2(ss, s, int(slen), width, flags);
}
/*
+4 -4
View File
@@ -2871,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;
}
@@ -2954,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;
}
-11
View File
@@ -7709,15 +7709,6 @@ SetContextOptions(JSContext* cx, const OptionParser& op)
return OptionFailure("ion-sincos", str);
}
if (const char* str = op.getStringOption("ion-sink")) {
if (strcmp(str, "on") == 0)
jit::JitOptions.disableSink = false;
else if (strcmp(str, "off") == 0)
jit::JitOptions.disableSink = true;
else
return OptionFailure("ion-sink", str);
}
if (const char* str = op.getStringOption("ion-loop-unrolling")) {
if (strcmp(str, "on") == 0)
jit::JitOptions.disableLoopUnrolling = false;
@@ -8093,8 +8084,6 @@ main(int argc, char** argv, char** envp)
|| !op.addStringOption('\0', "ion-sincos", "on/off",
"Replace sin(x)/cos(x) to sincos(x) (default: off, on to enable)")
#endif
|| !op.addStringOption('\0', "ion-sink", "on/off",
"Sink code motion (default: off, on to enable)")
|| !op.addStringOption('\0', "ion-loop-unrolling", "on/off",
"Loop unrolling (default: off, on to enable)")
|| !op.addStringOption('\0', "ion-instruction-reordering", "on/off",
+20 -20
View File
@@ -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
View File
@@ -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.
+2 -2
View File
@@ -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;
}
+7
View File
@@ -411,6 +411,13 @@ DottedCornerFinder::FindBestOverlap(Float aMinR, Float aMinBorderRadius,
mCount = mMaxCount;
break;
}
// GetCountAndLastOverlap() failed without writing |count| and
// |actualOverlap|: the walk needed more than mMaxCount circles, i.e.
// this overlap produces too many circles. Narrow the search toward
// smaller overlaps.
upper = overlap;
overlap = (upper + lower) / 2.0f;
continue;
}
if (j == 0) {
+17 -8
View File
@@ -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;
}
+18 -1
View File
@@ -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
+39
View File
@@ -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
+45 -7
View File
@@ -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
+37
View File
@@ -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
+1
View File
@@ -6,6 +6,7 @@
#ifndef WritingModes_h_
#define WritingModes_h_
#include "mozilla/LogicalTypes.h"
#include "nsRect.h"
#include "nsStyleContext.h"
#include "nsBidiUtils.h"
+2
View File
@@ -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',
+1 -1
View File
@@ -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
View File
@@ -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)) {
+5 -1
View File
@@ -318,7 +318,11 @@ nsHTMLFramesetFrame::Init(nsIContent* aContent,
mChildFrameborder[mChildCount] = GetFrameBorder(child);
mChildBorderColors[mChildCount].Set(GetBorderColor(child));
}
child->SetPrimaryFrame(frame);
if (MOZ_LIKELY(!child->GetPrimaryFrame())) {
// Child might have a pre-existing primary frame if we're doing fixed-pos
// replication... So, only set it if there is no primary frame yet.
child->SetPrimaryFrame(frame);
}
mFrames.AppendFrame(nullptr, frame);
+1 -2
View File
@@ -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
+6
View File
@@ -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.
+6 -4
View File
@@ -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);
}
+1 -1
View File
@@ -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();
Loaded 100 of 233 files, more files were not shown because too many files have changed in this diff. Show more