Files
palemoon27/layout/mathml/nsMathMLmunderoverFrame.cpp
roytam1 049b3235ac import changes from `dev' branch of rmottola/Arctic-Fox:
- Bug 1207494 - Part 8: Remove use of expression closure from dom/identity/. r=ferjm (34fac889f8)
- minor crash thing (13fe2827c2)
- Bug 1243359 - initialize mScrollSeriesNumber in all ScrollWheelInput constructors. r=roc (94163d8eca)
- fix misspatch (b380a7bbe4)
- Bug 1207412 - Make SystemTimeConverter use TimeStamp::Now() when converting times; r=karlt (f408549605)
- Bug 1212102 - Drop unnecessary assertion comparing timestamps in SystemTimeConverter; r=karlt (1efaa04b3f)
- Bug 1241302 - Slightly modernize this code. r=jst (c1e97bc069)
- bug 1216916 clean up when InvokeDragSessionWithImage/Selection() fails r=roc (9cdf71b717)
- Bug 1231329 - run ConvertToUnscaledDevPixels if *aPresContext is valid. r=roc (d10f23633b)
- Bug 1245927: Innerize before creating DOM files from the file picker. r=baku (8754128362)
- Bug 1155214 - Mark nsIBidiKeyboard as builtinclass; r=mrbkap (2d00326d2b)
- reorder (c3c1ba92c9)
- Bug 1236566 - add override declarations for widget/windows/GfxInfo.h; r=roc (940b40ed91)
- Bug 1242659: Part 1. More information on the mismatches. r=jrmuizel (78331ddad2)
- Block some Radeon drivers that crash on D3D9. (bug 1213107, r=jrmuizel) (482b66d313)
- Bug 1203199 - Blacklist DXVA on some older intel drivers for causing crashes. r=jrmuizel (f1827d4498)
- Bug 1203199 - Fix driver range with blacklist to avoid blacklisting other OSes. (2c2d547296)
- Bug 1203199 - Bustage fix. CLOSED TREE (3233d407f3)
- Bug 1178385. Enable DXVA on the G45 r=ajones (3c59a58a15)
- Bug 1188442 IMMHandler::GetSelection() should use static Selection instance when IME doesn't have focus and return its or mSelection's reference r=emk (5cc4b30433)
- Bug 1238899 Create hidden native caret for ATOK at composing in windowless plugin r=m_kato (40ef5bb4aa)
- Bug 1257919 part 1. Kill off nsIXSLTException. r=khuey (11f37643f2)
- Bug 1242072 - Change implementation of BaseProxyHandler::get() to follow ES6 [[Get]] specification. r=jorendorff (094a67f284)
- Bug 489636 - Add a GC u-bench test for property tree splitting via deletion; r=sfink (9282fec25f)
- Bug 1257919 part 2. Make nsIException and nsIStackFrame builtinclass, so we can start using [implicit_jscontext] on them. r=khuey (0e65fb8554)
- Bug 1257919 part 3. Make the various toString methods on exceptions take an explicit JSContext. r=khuey (b342fb4930)
- Bug 1257919 part 4. Stop returning StackFrame instances from exceptions::CreateStack. C++ callers of GetCurrentJSStack or exceptions::CreateStack always check for null anyway, and none of them seem to want this non-JS thing. r=khuey (d34036ccf9)
- Bug 1257919 part 5. Get rid of the now-unused StackFrame class. r=khuey (aa13af0dfe)
- Bug 1141222 - Create ScriptError with stack from Cu.reportError. r=bholley (b83ad26aa0)
- Bug 1208641 - Extract stack from DOM/XPC exception. r=bholley (e382b5f48c)
- Bug 1254380 part 1. Find the relevant window when the compartment we've got is an addon sandbox compartment in AutoJSAPI exception/warning reporting code. r=bholley (4b1f6c64a9)
- Bug 1250630 - remove PBackgroundTest and ifdef ENABLE_TEST blocks. r=khuey (d7b36860a3)
- Bug 1250963 part 1. Change NotifyRunnable::Dispatch to not require a JSContext. r=khuey (48e03c2fc2)
- Bug 1250963 part 2. Remove the unused JSContext argument of WorkerPrivate::ModifyBusyCount. r=khuey (0f5ca42be1)
- Bug 1250291 part 1. Stop pretending to report exceptions in MainThreadStopSyncLoopRunnable::PostDispatch. r=khuey (6e1c81cc06)
- Bug 1250291 part 2. Stop pretending to report exceptions in MainThreadWorkerSyncRunnable::PostDispatch. r=khuey (f3d846ea31)
- Bug 1250291 part 3. Stop pretending to report exceptions in WorkerDebuggerRunnable::PostDispatch. r=khuey (10bc1710d1)
- Bug 1250975. Stop passing a JSContext argument to WorkerRunnable::PreDispatch and its overrides. r=khuey (71ab9046f0)
- Bug 1255298. Just pass through the JSContext when passing through the NotificationOptions in notification code. r=wchen (552ae8e33e)
- Bug 1250185 part 2. Remove some JSContext stuff that's no longer needed in Notification code. r=khuey (20b99ef28b)
- Bug 1251045 part 8. Remove the JSContext argument from some nsINotificationStorageCallback methods. r=khuey (170c4afabc)
- Bug 1227015 P7 Supress unused ErrorResult exception if the worker runnable failed to dispatch. r=catalinb (23a3cc6f45)
- Bug 1251045 part 3. Remove the JSContext argument of WorkerRunnable::PostDispatch and its overrides. r=khuey (6a666d1a4a)
- Bug 1251045 part 2. Remove the JSContext argument of ModifyBusyCountFromWorker. r=khuey (105bc4f59e)
- Bug 1252130. Remove unnecessary JSContext argument from NotificationWorkerRunnable::WorkerRunInternal. r=khuey (642727f6f6)
- Bug 1252127. Remove unnecessary JSContext argument from PromiseWorkerProxy::CleanUp. r=khuey (339e1157d1)
- Bug 1251045 part 1. Make it possible to dispatch a ModifyBusyCountRunnable without a JSContext. r=khuey (665c1f81b4)
- Bug 1251045 part 4. Remove the JSContext argument of WorkerRunnable::Dispatch. r=khuey (6c5cdab2b7)
- Bug 1250185 part 1. nsIStructuredCloneContainer.initFromBase64 doesn't need a JSContext argument. r=khuey (d63a219209)
- fix (773c0393aa)
- Bug 1251045 part 5. Remove the JSContext argument from WorkerPrivateParent::Freeze/Thaw. r=khuey (cd419bfd2c)
- Bug 1251045 part 6. Remove the JSContext argument from some worker debugger methods that no longer need it. r=khuey (abcc437cb9)
- Bug 1251045 part 7. Remove the JSContext argument from some worker methods that no longer need it. r=khuey (3ddcbca08c)
- Bug 1249652 part 1. Add a method on ErrorResult to steal an exception, if any, from a JSContext. r=khuey (9c07f5044b)
- Bug 1229071 - importScripts should throw the correct error result in case the loading of one of scripts fails, r=bz (cd37645d76)
- Bug 1229970 Abort script loading start requests if a load has been canceled. r=khuey (a44d9128ca)
- Bug 1233171 Cancel channel when ScriptLoader is aborted during service worker script load. r=khuey (3b6ceafec7)
- Bug 1249351 part 1. When doing importScripts of multiple scripts in a service worker, make sure to track the cache streams per-loadinfo, instead of trying to make them all wait on the same stream. r=bkelly (e1ccea9685)
- Bug 1157544 - Fix a typo in the test; r=baku (8c0bf8f504)
- Bug 1249351 part 2. Clean up test_importscript.html and add multiple-url importScript() case. r=bz (52b0a31032)
- Bug 1249652 part 2. ScriptExecutorRunnable::WorkerRun should immediately move JS exceptions to its ErrorResult instead of allowing them to linger on the JSContext. r=baku,khuey (f628d3c8ba)
- Bug 1249652 part 3. Simplify way we handle canceling when ScriptLoaderRunnable::RunInternal fails by canceling things with its actual failure code, so we don't have to guess which failed loads are actual failures and which are just canceled via this mechanism. r=baku,khuey (388543fbc3)
- Bug 1251369. Use an AutoJSAPI that reports its own exceptions around the main runloop in workers. r=khuey (28b33287cd)
- Bug 1251518. Fix js::ErrorReportToString to make a bit more sense, and change worker code to not use it anyway, so it matches the mainthread code. r=bholley,terrence (a48a40de90)
- Bug 1254380 part 2. Go ahead and log the stack from our exception in AutoJSAPI::ReportException even if we don't have a window. r=bholley (64532b6017)
- Bug 1212328 - Clean up some JSErrorReport-related code. r=Waldo,bz (d5aa611edc)
- Bug 1255192 part 1. Remove the JSContext argument of JS::ExceptionStackOrNull. r=bholley (39b631d5ad)
- bug 1252687 - make the ctor for CycleCollectorStats constexpr r=mccr8 (9e8168d8ac)
- Bug 1254380 part 3. Skip firing error events for mainthread out of memory exceptions via AutoJSAPI::ReportException. r=bholley (d5e4e7dc29)
- Bug 1254230 kinda-fix. Make sure to never send script errors with stacks attached to the console service if the associated windows have already had FreeInnerObjects called on them. r=bholley (8c379fe0e0)
- Bug 1255192 part 2. Clean up the JSContext usage around xpc::FindExceptionStackForConsoleReport now that it just needs a JSContext for rooting. r=bholley (cade862491)
- Bug 1255201. Improve the stack handling in nsXPCComponents_Utils::ReportError for the DOMException case to include the stack from the DOMException. r=bholley (fc6c065284)
- Bug 1257919 part 6. Make the filename getter on JSStackFrame take an explicit JSContext. r=khuey (cde115b789)
- Bug 1257919 part 7. Make the name getter on JSStackFrame take an explicit JSContext. r=khuey (d7466e9eab)
- Bug 1257919 part 8. Make the line/column number getters on JSStackFrame take an explicit JSContext. r=khuey (b8766b98b2)
- Bug 1257919 part 9. Make the asyncCause/asyncCaller getters on JSStackFrame take an explicit JSContext. r=khuey (b776ff9c6d)
- Bug 1257919 part 10. Make the caller and formattedStack getters on JSStackFrame take an explicit JSContext. r=khuey (dc4d3d9091)
- Bug 1252091. Add/RemoveFeature don't need a JSContext argument. r=khuey (5be6253a67)
- Bug 1252123. Remove some unnecessary JSContext arguments from worker ScriptLoader methods. r=khuey (1657a35268)
- Bug 1255181. Remove AutoJSAPI::InitWithLegacyErrorReporting. r=bholley (5ee7ac506e)
- Bug 1254847 part 1. Take ownership of error reporting on the AutoEntryScript in nsXPCWrappedJSClass::DelegatedQueryInterface. r=bholley (62d987b030)
- make style wrong again.... (fa4e6cfbc1)
- Bug 1254847 part 2. Change nsJSNPRuntime to always use AutoEntryScript and always take ownership of error reporting. r=bholley (d24cb80622)
- Bug 1251655 - Remove support for JavaScript-global-constructor-prototype-alias. r=bz. (2b354ea423)
- Bug 1251655 - Remove support for JavaScript-DOM-class and JavaScript-DOM-interface. r=bz. (dd6786ea57)
- Bug 1251275. Switch to using an AutoEntryScript in WorkerPrivate::RunExpiredTimeouts. r=khuey (f10d1b0dec)
- Bug 1072144 part 1. Just release-assert that Promise::Resolve does not fail in service worker code. It can only do that on OOM or overrecursion anyway, and overrecursion is not likely if we're coming right off a runnable. r=khuey (ba4c89a3bc)
- Bug 1072144 part 2. When UnregisterWorker tries to ScheduleWorker and that throws, just suppress the exception: there is no good place to report it anyway. r=khuey (ca563ec5cd)
- Bug 1072144 part 3. Hoist the exception reporting out of WorkerRunnable::PostRun into WorkerRunnable::Run and make it unconditional. r=khuey (9914acd4a6)
- Bug 1252221. When GetOrCreateGlobalScope fails while trying to run a ScriptExecutorRunnable::WorkerRun, just suppress the exception, because there is no way to report it without a compartment to work with. r=khuey (abcc9df148)
- Bug 1072144 part 4. Add a WorkerRunnable::PreRun so that we can move worker global creation to it and always have an AutoEntryScript by the time we're evaluating the main worker script. r=khuey (007b528868)
- Bug 1251276 part 1. Change WorkerPrivate::CancelAllTimeouts to no longer call RunExpiredTimeouts. r=khuey (6b937370a1)
- Bug 1251276 part 2. Remove the JSContext argument of WorkerPrivate::CancelAllTimeouts. r=khuey (336b788e03)
- Bug 1251380. Change things so that WorkerPrivate::NotifyInternal (hopefully) never throws. r=khuey (1d4863f83a)
- Bug 1254846. Add an AutoEntryScript constructor that takes a JSObject instead of an nsIGlobalObject, for convenience. r=bholley (693857f9b0)
- Bug 1255706 part 1. Remove JSContext argument from WorkerPrivate constructor. r=khuey (0486bdb01c)
- Bug 1255706 part 2. Remove JSContext argument from WorkerPrivate::Terminate. r=khuey (f0b62de092)
- Bug 1257568. Remove the JSContext argument of WorkerPrivate::Kill. r=khuey (ebe7d247b5)
- Bug 1252189. Remove the unnecessary JSContext argument from WorkerPrivate::FreezeInternal/ThawInternal. r=khuey (22b137b05e)
- Bug 1119490 - Expose the URL constructor to WorkerDebuggerGlobalScope;r=khuey (6f4fc13e1e)
- Bug 1241841 - Clear the worker's debugger event queue before destroying its context;r=khuey (a1e8dd4b2d)
- Bug 1249950 - Add Performance Markers for MessagePort - patch 1 - remove non-useful 'explicit', r=smaug (8a014b53e6)
- Bug 1249950 - Add Performance Markers for MessagePort - patch 2, r=smaug, r=vporof (560caf0ae1)
- bug 1250486 - make the ComponentsSH ctor constexpr r=bz (1c441dbb0f)
- Bug 1257032: Make files in dom/workers actually build without unification. r=baku (6ab4ae0b65)
- Bug 1241522 - handle OOM in nsExpatDriver::HandleCharacterData; r=hsivonen (b652220cdc)
- Bug 1219482: Replace PRLogModuleInfo with LazyLogModule in various files.r=benjamin (5fd5e8dbc8)
- Bug 1238545 - Remove nsISimpleUnicharStreamFactory; r=froydnj (f0018c5b16)
- Bug 1257335. Replace some AutoSafeJSContext uses with AutoJSAPI or AutoJSContext uses. r=bholley (7baf79deb7)
- Bug 1247635 - Unify PostMessageRunnable and DispatchEventRunnable in MessagePort.cpp, r=smaug (df2765c215)
- Bug 1250572 - Force a parent object in MessagePort/Channel and in StructuredCloneHolder, r=smaug (2a929d59d1)
- Bug 1255375 - MessagePort should not leak if DispatchMessage() fails, r=smaug (0a5cdebfb0)
- Bug 1251272. Remove the dead code in ReportErrorRunnable::ReportError that could fail, and make it infallible. r=khuey (89e80694d0)
- Bug 1072144 part 5. Stop fiddling with compartments on the JSContext before calling PostRun in WorkerRunnable::Run. Add some documentation explaining what's going on. r=khuey (91f4bb6a7c)
- Bug 1072144 part 6. Switch WorkerRunnable::Run to calling TakeOwnershipOfErrorReporting on its AutoJSAPI/AutoEntryScript and remove the remaining JS_ReportPendingException callers in worker code. r=khuey (405d9e0282)
- Bug 1179548 - Close the windows opened in private browsing worker tests; r=baku (acf3430b69)
- Bug 1179753 - Use pushPrefEnv more in worker tests; r=baku (4bfd949c72)
- Bug 1134224 - More test for test_bug1132395.html, r=ehsan (626eb100cd)
- Bug 1134224 - onerror for test_bug1132395.html, r=ehsan (147195f57e)
- Bug 1207635 - get rid of dom.workers.sharedWorkers.enabled pref, r=khuey (22fe2965c6)
- Bug 1252592. JS warnings should not trigger error events on shared workers. r=khuey (7f05c2c00d)
- Bug 1251308; r=luke (3cbec95738)
- Bug 1246838 - Handle const qualifiers and references better in Variant. r=waldo (30da6e3ebf)
- Bug 1254565 - Allow passing matchers as rvalues to Variant::match. r=froydnj (1dd799fb0a)
- Bug 1246841 - Allow construction of Variant values using type inference. r=waldo (6ba3e6704c)
- Bug 1250666 - Forward Variant's move constructor argument correctly to the underlying variant type. r=waldo (7353a53bf0)
- Bug 1252185. Remove the dead "target" variable from CloseEventRunnable::WorkerRun. r=khuey (be172da10b)
- Bug 1253059: Use fallible allocation in the worker error reporter. r=baku (963222bdd4)
- Bug 1253199 - MessagePort should handle the dispatching a message when the parent window is gone, r=smaug (d552e3cd9e)
- Bug 1252839 - Remove some if stmt after allocation with 'new' - patch 2, r=bz (3c7eb959bc)
- Bug 1252839 - Remove some if stmt after allocation with 'new' - patch 1, r=bz (85067dbfb6)
- Bug 1254855. Switch AutoEntryScripts in nsDirectoryViewer to take ownership of error reporting. r=bholley (8c10532323)
- Bug 1252565 part 1. Push the script environment preparer bits up from XPCJSRuntime to CycleCollectedJSRuntime, because we need them on workers to do ctypes on workers properly. r=bholley (aecf2595dd)
- Bug 1252565 part 2. Make dom::WarningOnlyErrorReporter handle workers. r=bholley (f415b8868b)
- Bug 1244222 - Check for function interfaces in DelegatedQueryInterface. r=bz (d213eec83c)
- Bug 1254393. Take ownership of error reporting on the AutoEntryScript in nsXPCWrappedJSClass::CallMethod. r=bholley (4765b501c0)
- Bug 1251769 - Remove remaining references to MOZILLA_XPCOMRT_API from mfbt. r=froydnj (236adc1d4c)
- Bug 1247835 (part 0) - Minor comment and style tweaks in BinarySearch.h. r=luke. (db04793721)
- Bug 1244074 - Part 1: Move SheetParsingMode to a separate file. r=dholbert (290adaadea)
- Bug 1244074 - Part 2: Add HandleRefPtr for refcounting StyleSheetHandles. r=dholbert r=waldo (8549b24392)
- Bug 1244068 - Part 1: Add enum to represent the style system backend type. r=dholbert (c2e53feaf2)
- Bug 1244068 - Part 2: Add skeleton ServoStyleSet and a StyleSetHandle smart pointer. r=dholbert (71a5c28629)
- Bug 1244068 - Part 3: Factor out nsStyleSet getting in RestyleManager/ElementRestyler. r=dholbert (9e9f4f2e80)
- Bug 1245406: In ReflowBlockFrame, use Maybe<> to destroy & reconstruct a stack-allocated object, instead of an explicit call to destructor & placement 'new'. r=dbaron (d36858b818)
- Bug 1244068 - Part 4: Use StyleSetHandle instead of concrete style set class in most places. r=dholbert (93f9bcf799)
- Bug 1244074 - Part 3: Add skeleton ServoStyleSheet and a StyleSheetHandle smart pointer. r=dholbert (5b4fbdce38)
- Bug 1195173 - Apply CSP to preloaded styles within layout/style/Loader.cpp (r=bz) (d1ba920fd3)
- Bug 1245681 - Fix addOverrideStyleSheet. r=bz (64099eac73)
- Bug 1244074 - Part 4: Use StyleSheetHandle instead of concrete style sheet class in most places. r=dholberti (867470ac83)
- Bug 1246013 (part 1) - Store a copy of the ETLDEntry directly in DomainEntry instead of a pointer to it. r=jduell. (587b3a9fb7)
- Bug 1246013 (part 2) - Change "explicit/xpcom/effective-TLD-service" path to the more sensible "explicit/network/effective-TLD-service". r=jduell. (2e0df6f28f)
- Bug 1247835 (part 1) - Use binary search instead of a hash table in nsEffectiveTLDService. r=jduell. (685dae01c0)
- Bug 1257121 part 1 - Use struct for passing some params of font metrics. r=jfkthame (1dfd7a7429)
- Bug 1257121 part 2 - Merge nsFontMetrics::Init to the constructor and remove unused failure handling code. r=jfkthame (0cdc441511)
- Bug 1257121 part 3 - Add GetInflatedFontMetricsForFrame function to simplify a common use pattern. r=jfkthame (d9630ebd1b)
- Bug 1257121 part 4 - Use return value rather than out param to retur font metrics. r=jfkthame (c9a5b1d1dd)
- Bug 1257121 part 5 - Make nsDeviceContext::mFontCache a RefPtr. r=jfkthame (9c53238a6a)
2024-01-29 15:26:23 +08:00

686 lines
26 KiB
C++

/* -*- 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/. */
#include "nsMathMLmunderoverFrame.h"
#include "nsPresContext.h"
#include "nsRenderingContext.h"
#include "nsMathMLmmultiscriptsFrame.h"
#include <algorithm>
//
// <munderover> -- attach an underscript-overscript pair to a base - implementation
// <mover> -- attach an overscript to a base - implementation
// <munder> -- attach an underscript to a base - implementation
//
nsIFrame*
NS_NewMathMLmunderoverFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
{
return new (aPresShell) nsMathMLmunderoverFrame(aContext);
}
NS_IMPL_FRAMEARENA_HELPERS(nsMathMLmunderoverFrame)
nsMathMLmunderoverFrame::~nsMathMLmunderoverFrame()
{
}
nsresult
nsMathMLmunderoverFrame::AttributeChanged(int32_t aNameSpaceID,
nsIAtom* aAttribute,
int32_t aModType)
{
if (nsGkAtoms::accent_ == aAttribute ||
nsGkAtoms::accentunder_ == aAttribute) {
// When we have automatic data to update within ourselves, we ask our
// parent to re-layout its children
return ReLayoutChildren(GetParent());
}
return nsMathMLContainerFrame::
AttributeChanged(aNameSpaceID, aAttribute, aModType);
}
NS_IMETHODIMP
nsMathMLmunderoverFrame::UpdatePresentationData(uint32_t aFlagsValues,
uint32_t aFlagsToUpdate)
{
nsMathMLContainerFrame::UpdatePresentationData(aFlagsValues, aFlagsToUpdate);
// disable the stretch-all flag if we are going to act like a subscript-superscript pair
if (NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(mEmbellishData.flags) &&
StyleFont()->mMathDisplay == NS_MATHML_DISPLAYSTYLE_INLINE) {
mPresentationData.flags &= ~NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY;
}
else {
mPresentationData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY;
}
return NS_OK;
}
NS_IMETHODIMP
nsMathMLmunderoverFrame::InheritAutomaticData(nsIFrame* aParent)
{
// let the base class get the default from our parent
nsMathMLContainerFrame::InheritAutomaticData(aParent);
mPresentationData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY;
return NS_OK;
}
uint8_t
nsMathMLmunderoverFrame::ScriptIncrement(nsIFrame* aFrame)
{
nsIFrame* child = mFrames.FirstChild();
if (!aFrame || aFrame == child) {
return 0;
}
child = child->GetNextSibling();
if (aFrame == child) {
if (mContent->IsMathMLElement(nsGkAtoms::mover_)) {
return mIncrementOver ? 1 : 0;
}
return mIncrementUnder ? 1 : 0;
}
if (child && aFrame == child->GetNextSibling()) {
// must be a over frame of munderover
return mIncrementOver ? 1 : 0;
}
return 0; // frame not found
}
NS_IMETHODIMP
nsMathMLmunderoverFrame::TransmitAutomaticData()
{
// At this stage, all our children are in sync and we can fully
// resolve our own mEmbellishData struct
//---------------------------------------------------------------------
/*
The REC says:
As regards munder (respectively mover) :
The default value of accentunder is false, unless underscript
is an <mo> element or an embellished operator. If underscript is
an <mo> element, the value of its accent attribute is used as the
default value of accentunder. If underscript is an embellished
operator, the accent attribute of the <mo> element at its
core is used as the default value. As with all attributes, an
explicitly given value overrides the default.
XXX The winner is the outermost setting in conflicting settings like these:
<munder accentunder='true'>
<mi>...</mi>
<mo accentunder='false'> ... </mo>
</munder>
As regards munderover:
The accent and accentunder attributes have the same effect as
the attributes with the same names on <mover> and <munder>,
respectively. Their default values are also computed in the
same manner as described for those elements, with the default
value of accent depending on overscript and the default value
of accentunder depending on underscript.
*/
nsIFrame* overscriptFrame = nullptr;
nsIFrame* underscriptFrame = nullptr;
nsIFrame* baseFrame = mFrames.FirstChild();
if (baseFrame) {
if (mContent->IsAnyOfMathMLElements(nsGkAtoms::munder_,
nsGkAtoms::munderover_)) {
underscriptFrame = baseFrame->GetNextSibling();
} else {
NS_ASSERTION(mContent->IsMathMLElement(nsGkAtoms::mover_),
"mContent->NodeInfo()->NameAtom() not recognized");
overscriptFrame = baseFrame->GetNextSibling();
}
}
if (underscriptFrame &&
mContent->IsMathMLElement(nsGkAtoms::munderover_)) {
overscriptFrame = underscriptFrame->GetNextSibling();
}
// if our base is an embellished operator, let its state bubble to us (in particular,
// this is where we get the flag for NS_MATHML_EMBELLISH_MOVABLELIMITS). Our flags
// are reset to the default values of false if the base frame isn't embellished.
mPresentationData.baseFrame = baseFrame;
GetEmbellishDataFrom(baseFrame, mEmbellishData);
// The default value of accentunder is false, unless the underscript is embellished
// and its core <mo> is an accent
nsEmbellishData embellishData;
nsAutoString value;
if (mContent->IsAnyOfMathMLElements(nsGkAtoms::munder_,
nsGkAtoms::munderover_)) {
GetEmbellishDataFrom(underscriptFrame, embellishData);
if (NS_MATHML_EMBELLISH_IS_ACCENT(embellishData.flags)) {
mEmbellishData.flags |= NS_MATHML_EMBELLISH_ACCENTUNDER;
} else {
mEmbellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENTUNDER;
}
// if we have an accentunder attribute, it overrides what the underscript said
if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::accentunder_, value)) {
if (value.EqualsLiteral("true")) {
mEmbellishData.flags |= NS_MATHML_EMBELLISH_ACCENTUNDER;
} else if (value.EqualsLiteral("false")) {
mEmbellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENTUNDER;
}
}
}
// The default value of accent is false, unless the overscript is embellished
// and its core <mo> is an accent
if (mContent->IsAnyOfMathMLElements(nsGkAtoms::mover_,
nsGkAtoms::munderover_)) {
GetEmbellishDataFrom(overscriptFrame, embellishData);
if (NS_MATHML_EMBELLISH_IS_ACCENT(embellishData.flags)) {
mEmbellishData.flags |= NS_MATHML_EMBELLISH_ACCENTOVER;
} else {
mEmbellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENTOVER;
}
// if we have an accent attribute, it overrides what the overscript said
if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::accent_, value)) {
if (value.EqualsLiteral("true")) {
mEmbellishData.flags |= NS_MATHML_EMBELLISH_ACCENTOVER;
} else if (value.EqualsLiteral("false")) {
mEmbellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENTOVER;
}
}
}
bool subsupDisplay =
NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(mEmbellishData.flags) &&
StyleFont()->mMathDisplay == NS_MATHML_DISPLAYSTYLE_INLINE;
// disable the stretch-all flag if we are going to act like a superscript
if (subsupDisplay) {
mPresentationData.flags &= ~NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY;
}
// Now transmit any change that we want to our children so that they
// can update their mPresentationData structs
//---------------------------------------------------------------------
/* The REC says:
Within underscript, <munderover> always sets displaystyle to "false",
but increments scriptlevel by 1 only when accentunder is "false".
Within overscript, <munderover> always sets displaystyle to "false",
but increments scriptlevel by 1 only when accent is "false".
Within subscript and superscript it increments scriptlevel by 1, and
sets displaystyle to "false", but leaves both attributes unchanged within
base.
The TeXBook treats 'over' like a superscript, so p.141 or Rule 13a
say it shouldn't be compressed. However, The TeXBook says
that math accents and \overline change uncramped styles to their
cramped counterparts.
*/
if (mContent->IsAnyOfMathMLElements(nsGkAtoms::mover_,
nsGkAtoms::munderover_)) {
uint32_t compress = NS_MATHML_EMBELLISH_IS_ACCENTOVER(mEmbellishData.flags)
? NS_MATHML_COMPRESSED : 0;
mIncrementOver =
!NS_MATHML_EMBELLISH_IS_ACCENTOVER(mEmbellishData.flags) ||
subsupDisplay;
SetIncrementScriptLevel(mContent->IsMathMLElement(nsGkAtoms::mover_) ? 1 : 2, mIncrementOver);
if (mIncrementOver) {
PropagateFrameFlagFor(overscriptFrame,
NS_FRAME_MATHML_SCRIPT_DESCENDANT);
}
PropagatePresentationDataFor(overscriptFrame, compress, compress);
}
/*
The TeXBook treats 'under' like a subscript, so p.141 or Rule 13a
say it should be compressed
*/
if (mContent->IsAnyOfMathMLElements(nsGkAtoms::munder_,
nsGkAtoms::munderover_)) {
mIncrementUnder =
!NS_MATHML_EMBELLISH_IS_ACCENTUNDER(mEmbellishData.flags) ||
subsupDisplay;
SetIncrementScriptLevel(1, mIncrementUnder);
if (mIncrementUnder) {
PropagateFrameFlagFor(underscriptFrame,
NS_FRAME_MATHML_SCRIPT_DESCENDANT);
}
PropagatePresentationDataFor(underscriptFrame,
NS_MATHML_COMPRESSED,
NS_MATHML_COMPRESSED);
}
/* Set flags for dtls font feature settings.
dtls
Dotless Forms
This feature provides dotless forms for Math Alphanumeric
characters, such as U+1D422 MATHEMATICAL BOLD SMALL I,
U+1D423 MATHEMATICAL BOLD SMALL J, U+1D456
U+MATHEMATICAL ITALIC SMALL I, U+1D457 MATHEMATICAL ITALIC
SMALL J, and so on.
The dotless forms are to be used as base forms for placing
mathematical accents over them.
To opt out of this change, add the following to the stylesheet:
"font-feature-settings: 'dtls' 0"
*/
if (overscriptFrame &&
NS_MATHML_EMBELLISH_IS_ACCENTOVER(mEmbellishData.flags) &&
!NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(mEmbellishData.flags)) {
PropagatePresentationDataFor(baseFrame, NS_MATHML_DTLS, NS_MATHML_DTLS);
}
return NS_OK;
}
/*
The REC says:
* If the base is an operator with movablelimits="true" (or an embellished
operator whose <mo> element core has movablelimits="true"), and
displaystyle="false", then underscript and overscript are drawn in
a subscript and superscript position, respectively. In this case,
the accent and accentunder attributes are ignored. This is often
used for limits on symbols such as &sum;.
i.e.,:
if (NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(mEmbellishDataflags) &&
StyleFont()->mMathDisplay == NS_MATHML_DISPLAYSTYLE_INLINE) {
// place like subscript-superscript pair
}
else {
// place like underscript-overscript pair
}
*/
/* virtual */ nsresult
nsMathMLmunderoverFrame::Place(DrawTarget* aDrawTarget,
bool aPlaceOrigin,
nsHTMLReflowMetrics& aDesiredSize)
{
float fontSizeInflation = nsLayoutUtils::FontSizeInflationFor(this);
if (NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(mEmbellishData.flags) &&
StyleFont()->mMathDisplay == NS_MATHML_DISPLAYSTYLE_INLINE) {
//place like sub sup or subsup
if (mContent->IsMathMLElement(nsGkAtoms::munderover_)) {
return nsMathMLmmultiscriptsFrame::PlaceMultiScript(PresContext(),
aDrawTarget,
aPlaceOrigin,
aDesiredSize,
this, 0, 0,
fontSizeInflation);
} else if (mContent->IsMathMLElement( nsGkAtoms::munder_)) {
return nsMathMLmmultiscriptsFrame::PlaceMultiScript(PresContext(),
aDrawTarget,
aPlaceOrigin,
aDesiredSize,
this, 0, 0,
fontSizeInflation);
} else {
NS_ASSERTION(mContent->IsMathMLElement(nsGkAtoms::mover_),
"mContent->NodeInfo()->NameAtom() not recognized");
return nsMathMLmmultiscriptsFrame::PlaceMultiScript(PresContext(),
aDrawTarget,
aPlaceOrigin,
aDesiredSize,
this, 0, 0,
fontSizeInflation);
}
}
////////////////////////////////////
// Get the children's desired sizes
nsBoundingMetrics bmBase, bmUnder, bmOver;
nsHTMLReflowMetrics baseSize(aDesiredSize.GetWritingMode());
nsHTMLReflowMetrics underSize(aDesiredSize.GetWritingMode());
nsHTMLReflowMetrics overSize(aDesiredSize.GetWritingMode());
nsIFrame* overFrame = nullptr;
nsIFrame* underFrame = nullptr;
nsIFrame* baseFrame = mFrames.FirstChild();
underSize.SetBlockStartAscent(0);
overSize.SetBlockStartAscent(0);
bool haveError = false;
if (baseFrame) {
if (mContent->IsAnyOfMathMLElements(nsGkAtoms::munder_,
nsGkAtoms::munderover_)) {
underFrame = baseFrame->GetNextSibling();
} else if (mContent->IsMathMLElement(nsGkAtoms::mover_)) {
overFrame = baseFrame->GetNextSibling();
}
}
if (underFrame && mContent->IsMathMLElement(nsGkAtoms::munderover_)) {
overFrame = underFrame->GetNextSibling();
}
if (mContent->IsMathMLElement(nsGkAtoms::munder_)) {
if (!baseFrame || !underFrame || underFrame->GetNextSibling()) {
// report an error, encourage people to get their markups in order
haveError = true;
}
}
if (mContent->IsMathMLElement(nsGkAtoms::mover_)) {
if (!baseFrame || !overFrame || overFrame->GetNextSibling()) {
// report an error, encourage people to get their markups in order
haveError = true;
}
}
if (mContent->IsMathMLElement(nsGkAtoms::munderover_)) {
if (!baseFrame || !underFrame || !overFrame || overFrame->GetNextSibling()) {
// report an error, encourage people to get their markups in order
haveError = true;
}
}
if (haveError) {
if (aPlaceOrigin) {
ReportChildCountError();
}
return ReflowError(aDrawTarget, aDesiredSize);
}
GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase);
if (underFrame) {
GetReflowAndBoundingMetricsFor(underFrame, underSize, bmUnder);
}
if (overFrame) {
GetReflowAndBoundingMetricsFor(overFrame, overSize, bmOver);
}
nscoord onePixel = nsPresContext::CSSPixelsToAppUnits(1);
////////////////////
// Place Children
RefPtr<nsFontMetrics> fm =
nsLayoutUtils::GetFontMetricsForFrame(this, fontSizeInflation);
nscoord xHeight = fm->XHeight();
nscoord oneDevPixel = fm->AppUnitsPerDevPixel();
gfxFont* mathFont = fm->GetThebesFontGroup()->GetFirstMathFont();
nscoord ruleThickness;
GetRuleThickness (aDrawTarget, fm, ruleThickness);
nscoord correction = 0;
GetItalicCorrection (bmBase, correction);
// there are 2 different types of placement depending on
// whether we want an accented under or not
nscoord underDelta1 = 0; // gap between base and underscript
nscoord underDelta2 = 0; // extra space beneath underscript
if (!NS_MATHML_EMBELLISH_IS_ACCENTUNDER(mEmbellishData.flags)) {
// Rule 13a, App. G, TeXbook
nscoord bigOpSpacing2, bigOpSpacing4, bigOpSpacing5, dummy;
GetBigOpSpacings (fm,
dummy, bigOpSpacing2,
dummy, bigOpSpacing4,
bigOpSpacing5);
if (mathFont) {
// XXXfredw The Open Type MATH table has some StretchStack* parameters
// that we may use when the base is a stretchy horizontal operator. See
// bug 963131.
bigOpSpacing2 =
mathFont->GetMathConstant(gfxFontEntry::LowerLimitGapMin,
oneDevPixel);
bigOpSpacing4 =
mathFont->GetMathConstant(gfxFontEntry::LowerLimitBaselineDropMin,
oneDevPixel);
bigOpSpacing5 = 0;
}
underDelta1 = std::max(bigOpSpacing2, (bigOpSpacing4 - bmUnder.ascent));
underDelta2 = bigOpSpacing5;
}
else {
// No corresponding rule in TeXbook - we are on our own here
// XXX tune the gap delta between base and underscript
// XXX Should we use Rule 10 like \underline does?
// XXXfredw Perhaps use the Underbar* parameters of the MATH table. See
// bug 963125.
underDelta1 = ruleThickness + onePixel/2;
underDelta2 = ruleThickness;
}
// empty under?
if (!(bmUnder.ascent + bmUnder.descent)) {
underDelta1 = 0;
underDelta2 = 0;
}
nscoord overDelta1 = 0; // gap between base and overscript
nscoord overDelta2 = 0; // extra space above overscript
if (!NS_MATHML_EMBELLISH_IS_ACCENTOVER(mEmbellishData.flags)) {
// Rule 13a, App. G, TeXbook
// XXXfredw The Open Type MATH table has some StretchStack* parameters
// that we may use when the base is a stretchy horizontal operator. See
// bug 963131.
nscoord bigOpSpacing1, bigOpSpacing3, bigOpSpacing5, dummy;
GetBigOpSpacings (fm,
bigOpSpacing1, dummy,
bigOpSpacing3, dummy,
bigOpSpacing5);
if (mathFont) {
// XXXfredw The Open Type MATH table has some StretchStack* parameters
// that we may use when the base is a stretchy horizontal operator. See
// bug 963131.
bigOpSpacing1 =
mathFont->GetMathConstant(gfxFontEntry::UpperLimitGapMin,
oneDevPixel);
bigOpSpacing3 =
mathFont->GetMathConstant(gfxFontEntry::UpperLimitBaselineRiseMin,
oneDevPixel);
bigOpSpacing5 = 0;
}
overDelta1 = std::max(bigOpSpacing1, (bigOpSpacing3 - bmOver.descent));
overDelta2 = bigOpSpacing5;
// XXX This is not a TeX rule...
// delta1 (as computed abvove) can become really big when bmOver.descent is
// negative, e.g., if the content is &OverBar. In such case, we use the height
if (bmOver.descent < 0)
overDelta1 = std::max(bigOpSpacing1, (bigOpSpacing3 - (bmOver.ascent + bmOver.descent)));
}
else {
// Rule 12, App. G, TeXbook
// We are going to modify this rule to make it more general.
// The idea behind Rule 12 in the TeXBook is to keep the accent
// as close to the base as possible, while ensuring that the
// distance between the *baseline* of the accent char and
// the *baseline* of the base is atleast x-height.
// The idea is that for normal use, we would like all the accents
// on a line to line up atleast x-height above the baseline
// if possible.
// When the ascent of the base is >= x-height,
// the baseline of the accent char is placed just above the base
// (specifically, the baseline of the accent char is placed
// above the baseline of the base by the ascent of the base).
// For ease of implementation,
// this assumes that the font-designer designs accents
// in such a way that the bottom of the accent is atleast x-height
// above its baseline, otherwise there will be collisions
// with the base. Also there should be proper padding between
// the bottom of the accent char and its baseline.
// The above rule may not be obvious from a first
// reading of rule 12 in the TeXBook !!!
// The mathml <mover> tag can use accent chars that
// do not follow this convention. So we modify TeX's rule
// so that TeX's rule gets subsumed for accents that follow
// TeX's convention,
// while also allowing accents that do not follow the convention :
// we try to keep the *bottom* of the accent char atleast x-height
// from the baseline of the base char. we also slap on an extra
// padding between the accent and base chars.
overDelta1 = ruleThickness + onePixel/2;
nscoord accentBaseHeight = xHeight;
if (mathFont) {
accentBaseHeight =
mathFont->GetMathConstant(gfxFontEntry::AccentBaseHeight,
oneDevPixel);
}
if (bmBase.ascent < accentBaseHeight) {
// also ensure at least accentBaseHeight above the baseline of the base
overDelta1 += accentBaseHeight - bmBase.ascent;
}
overDelta2 = ruleThickness;
}
// empty over?
if (!(bmOver.ascent + bmOver.descent)) {
overDelta1 = 0;
overDelta2 = 0;
}
nscoord dxBase = 0, dxOver = 0, dxUnder = 0;
nsAutoString valueAlign;
enum {
center,
left,
right
} alignPosition = center;
if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::align, valueAlign)) {
if (valueAlign.EqualsLiteral("left")) {
alignPosition = left;
} else if (valueAlign.EqualsLiteral("right")) {
alignPosition = right;
}
}
//////////
// pass 1, do what <mover> does: attach the overscript on the base
// Ad-hoc - This is to override fonts which have ready-made _accent_
// glyphs with negative lbearing and rbearing. We want to position
// the overscript ourselves
nscoord overWidth = bmOver.width;
if (!overWidth && (bmOver.rightBearing - bmOver.leftBearing > 0)) {
overWidth = bmOver.rightBearing - bmOver.leftBearing;
dxOver = -bmOver.leftBearing;
}
if (NS_MATHML_EMBELLISH_IS_ACCENTOVER(mEmbellishData.flags)) {
mBoundingMetrics.width = bmBase.width;
if (alignPosition == center) {
dxOver += correction;
}
}
else {
mBoundingMetrics.width = std::max(bmBase.width, overWidth);
if (alignPosition == center) {
dxOver += correction/2;
}
}
if (alignPosition == center) {
dxOver += (mBoundingMetrics.width - overWidth)/2;
dxBase = (mBoundingMetrics.width - bmBase.width)/2;
} else if (alignPosition == right) {
dxOver += mBoundingMetrics.width - overWidth;
dxBase = mBoundingMetrics.width - bmBase.width;
}
mBoundingMetrics.ascent =
bmBase.ascent + overDelta1 + bmOver.ascent + bmOver.descent;
mBoundingMetrics.descent = bmBase.descent;
mBoundingMetrics.leftBearing =
std::min(dxBase + bmBase.leftBearing, dxOver + bmOver.leftBearing);
mBoundingMetrics.rightBearing =
std::max(dxBase + bmBase.rightBearing, dxOver + bmOver.rightBearing);
//////////
// pass 2, do what <munder> does: attach the underscript on the previous
// result. We conceptually view the previous result as an "anynomous base"
// from where to attach the underscript. Hence if the underscript is empty,
// we should end up like <mover>. If the overscript is empty, we should
// end up like <munder>.
nsBoundingMetrics bmAnonymousBase = mBoundingMetrics;
nscoord ascentAnonymousBase =
std::max(mBoundingMetrics.ascent + overDelta2,
overSize.BlockStartAscent() + bmOver.descent +
overDelta1 + bmBase.ascent);
ascentAnonymousBase = std::max(ascentAnonymousBase,
baseSize.BlockStartAscent());
// Width of non-spacing marks is zero so use left and right bearing.
nscoord underWidth = bmUnder.width;
if (!underWidth) {
underWidth = bmUnder.rightBearing - bmUnder.leftBearing;
dxUnder = -bmUnder.leftBearing;
}
nscoord maxWidth = std::max(bmAnonymousBase.width, underWidth);
if (alignPosition == center &&
!NS_MATHML_EMBELLISH_IS_ACCENTUNDER(mEmbellishData.flags)) {
GetItalicCorrection(bmAnonymousBase, correction);
dxUnder += -correction/2;
}
nscoord dxAnonymousBase = 0;
if (alignPosition == center) {
dxUnder += (maxWidth - underWidth)/2;
dxAnonymousBase = (maxWidth - bmAnonymousBase.width)/2;
} else if (alignPosition == right) {
dxUnder += maxWidth - underWidth;
dxAnonymousBase = maxWidth - bmAnonymousBase.width;
}
// adjust the offsets of the real base and overscript since their
// final offsets should be relative to us...
dxOver += dxAnonymousBase;
dxBase += dxAnonymousBase;
mBoundingMetrics.width =
std::max(dxAnonymousBase + bmAnonymousBase.width, dxUnder + bmUnder.width);
// At this point, mBoundingMetrics.ascent = bmAnonymousBase.ascent
mBoundingMetrics.descent =
bmAnonymousBase.descent + underDelta1 + bmUnder.ascent + bmUnder.descent;
mBoundingMetrics.leftBearing =
std::min(dxAnonymousBase + bmAnonymousBase.leftBearing, dxUnder + bmUnder.leftBearing);
mBoundingMetrics.rightBearing =
std::max(dxAnonymousBase + bmAnonymousBase.rightBearing, dxUnder + bmUnder.rightBearing);
aDesiredSize.SetBlockStartAscent(ascentAnonymousBase);
aDesiredSize.Height() = aDesiredSize.BlockStartAscent() +
std::max(mBoundingMetrics.descent + underDelta2,
bmAnonymousBase.descent + underDelta1 + bmUnder.ascent +
underSize.Height() - underSize.BlockStartAscent());
aDesiredSize.Height() = std::max(aDesiredSize.Height(),
aDesiredSize.BlockStartAscent() +
baseSize.Height() - baseSize.BlockStartAscent());
aDesiredSize.Width() = mBoundingMetrics.width;
aDesiredSize.mBoundingMetrics = mBoundingMetrics;
mReference.x = 0;
mReference.y = aDesiredSize.BlockStartAscent();
if (aPlaceOrigin) {
nscoord dy;
// place overscript
if (overFrame) {
dy = aDesiredSize.BlockStartAscent() -
mBoundingMetrics.ascent + bmOver.ascent -
overSize.BlockStartAscent();
FinishReflowChild (overFrame, PresContext(), overSize, nullptr, dxOver, dy, 0);
}
// place base
dy = aDesiredSize.BlockStartAscent() - baseSize.BlockStartAscent();
FinishReflowChild (baseFrame, PresContext(), baseSize, nullptr, dxBase, dy, 0);
// place underscript
if (underFrame) {
dy = aDesiredSize.BlockStartAscent() +
mBoundingMetrics.descent - bmUnder.descent -
underSize.BlockStartAscent();
FinishReflowChild (underFrame, PresContext(), underSize, nullptr,
dxUnder, dy, 0);
}
}
return NS_OK;
}