2017-10-27 20:33:53 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
2012-05-21 15:12:37 +04:00
|
|
|
/* 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/. */
|
2001-02-23 19:09:14 +03:00
|
|
|
|
|
|
|
#include "nsMathMLFrame.h"
|
2014-10-17 18:06:34 +04:00
|
|
|
|
2017-06-09 22:14:53 +03:00
|
|
|
#include "gfxContext.h"
|
2014-10-17 18:06:34 +04:00
|
|
|
#include "gfxUtils.h"
|
|
|
|
#include "mozilla/gfx/2D.h"
|
|
|
|
#include "nsLayoutUtils.h"
|
2014-02-28 03:04:46 +04:00
|
|
|
#include "nsNameSpaceManager.h"
|
2002-01-09 21:51:30 +03:00
|
|
|
#include "nsMathMLChar.h"
|
2009-12-11 10:37:40 +03:00
|
|
|
#include "nsCSSPseudoElements.h"
|
2013-08-31 01:37:12 +04:00
|
|
|
#include "nsMathMLElement.h"
|
2016-11-02 21:47:18 +03:00
|
|
|
#include "gfxMathTable.h"
|
2001-02-23 19:09:14 +03:00
|
|
|
|
2002-02-14 15:26:43 +03:00
|
|
|
// used to map attributes into CSS rules
|
2018-03-29 14:15:46 +03:00
|
|
|
#include "mozilla/ServoStyleSet.h"
|
2006-01-26 05:29:17 +03:00
|
|
|
#include "nsDisplayList.h"
|
|
|
|
|
2014-10-17 18:06:34 +04:00
|
|
|
using namespace mozilla;
|
|
|
|
using namespace mozilla::gfx;
|
|
|
|
|
2006-08-15 08:49:43 +04:00
|
|
|
eMathMLFrameType nsMathMLFrame::GetMathMLFrameType() {
|
|
|
|
// see if it is an embellished operator (mapped to 'Op' in TeX)
|
|
|
|
if (mEmbellishData.coreFrame)
|
|
|
|
return GetMathMLFrameTypeFor(mEmbellishData.coreFrame);
|
|
|
|
|
|
|
|
// if it has a prescribed base, fetch the type from there
|
|
|
|
if (mPresentationData.baseFrame)
|
|
|
|
return GetMathMLFrameTypeFor(mPresentationData.baseFrame);
|
|
|
|
|
|
|
|
// everything else is treated as ordinary (mapped to 'Ord' in TeX)
|
2017-07-06 15:00:35 +03:00
|
|
|
return eMathMLFrameType_Ordinary;
|
2006-08-15 08:49:43 +04:00
|
|
|
}
|
|
|
|
|
2002-02-01 18:10:50 +03:00
|
|
|
NS_IMETHODIMP
|
2017-07-06 15:00:35 +03:00
|
|
|
nsMathMLFrame::InheritAutomaticData(nsIFrame* aParent) {
|
2002-02-02 08:43:03 +03:00
|
|
|
mEmbellishData.flags = 0;
|
2012-07-30 18:20:58 +04:00
|
|
|
mEmbellishData.coreFrame = nullptr;
|
2002-02-01 18:10:50 +03:00
|
|
|
mEmbellishData.direction = NS_STRETCH_DIRECTION_UNSUPPORTED;
|
2011-12-22 02:21:59 +04:00
|
|
|
mEmbellishData.leadingSpace = 0;
|
|
|
|
mEmbellishData.trailingSpace = 0;
|
2002-02-07 07:38:08 +03:00
|
|
|
|
|
|
|
mPresentationData.flags = 0;
|
2012-07-30 18:20:58 +04:00
|
|
|
mPresentationData.baseFrame = nullptr;
|
2002-02-01 18:10:50 +03:00
|
|
|
|
2008-01-09 12:38:28 +03:00
|
|
|
// by default, just inherit the display of our parent
|
2002-02-07 07:38:08 +03:00
|
|
|
nsPresentationData parentData;
|
|
|
|
GetPresentationDataFrom(aParent, parentData);
|
|
|
|
|
2012-06-25 23:59:42 +04:00
|
|
|
#if defined(DEBUG) && defined(SHOW_BOUNDING_BOX)
|
2002-02-07 07:38:08 +03:00
|
|
|
mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS;
|
|
|
|
#endif
|
|
|
|
|
2002-02-01 18:10:50 +03:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2001-02-23 19:09:14 +03:00
|
|
|
NS_IMETHODIMP
|
2012-08-22 19:56:38 +04:00
|
|
|
nsMathMLFrame::UpdatePresentationData(uint32_t aFlagsValues,
|
|
|
|
uint32_t aWhichFlags) {
|
2014-09-24 12:33:00 +04:00
|
|
|
NS_ASSERTION(NS_MATHML_IS_COMPRESSED(aWhichFlags) ||
|
|
|
|
NS_MATHML_IS_DTLS_SET(aWhichFlags),
|
|
|
|
"aWhichFlags should only be compression or dtls flag");
|
2014-01-14 18:39:50 +04:00
|
|
|
|
2006-09-19 08:43:14 +04:00
|
|
|
if (NS_MATHML_IS_COMPRESSED(aWhichFlags)) {
|
2001-02-23 19:09:14 +03:00
|
|
|
// updating the compression flag is allowed
|
|
|
|
if (NS_MATHML_IS_COMPRESSED(aFlagsValues)) {
|
|
|
|
// 'compressed' means 'prime' style in App. G, TeXbook
|
|
|
|
mPresentationData.flags |= NS_MATHML_COMPRESSED;
|
|
|
|
}
|
|
|
|
// no else. the flag is sticky. it retains its value once it is set
|
|
|
|
}
|
2014-09-24 12:33:00 +04:00
|
|
|
// These flags determine whether the dtls font feature settings should
|
|
|
|
// be applied.
|
|
|
|
if (NS_MATHML_IS_DTLS_SET(aWhichFlags)) {
|
|
|
|
if (NS_MATHML_IS_DTLS_SET(aFlagsValues)) {
|
|
|
|
mPresentationData.flags |= NS_MATHML_DTLS;
|
|
|
|
} else {
|
|
|
|
mPresentationData.flags &= ~NS_MATHML_DTLS;
|
|
|
|
}
|
|
|
|
}
|
2001-02-23 19:09:14 +03:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2002-01-09 21:51:30 +03:00
|
|
|
|
2018-03-23 16:49:21 +03:00
|
|
|
// Helper to give a ComputedStyle suitable for doing the stretching of
|
2017-07-06 15:00:35 +03:00
|
|
|
// a MathMLChar. Frame classes that use this should ensure that the
|
2018-03-23 16:49:21 +03:00
|
|
|
// extra leaf ComputedStyle given to the MathMLChars are accessible to
|
2018-03-22 21:20:41 +03:00
|
|
|
// the Style System via the Get/Set AdditionalComputedStyle() APIs.
|
2004-08-01 03:15:21 +04:00
|
|
|
/* static */ void nsMathMLFrame::ResolveMathMLCharStyle(
|
|
|
|
nsPresContext* aPresContext, nsIContent* aContent,
|
2018-03-22 21:20:41 +03:00
|
|
|
ComputedStyle* aParentComputedStyle, nsMathMLChar* aMathMLChar) {
|
2016-02-17 23:37:00 +03:00
|
|
|
CSSPseudoElementType pseudoType =
|
2016-02-17 01:07:00 +03:00
|
|
|
CSSPseudoElementType::mozMathAnonymous; // savings
|
2018-03-22 21:20:41 +03:00
|
|
|
RefPtr<ComputedStyle> newComputedStyle;
|
|
|
|
newComputedStyle = aPresContext->StyleSet()->ResolvePseudoElementStyle(
|
2010-04-30 17:12:06 +04:00
|
|
|
aContent->AsElement(), pseudoType, aParentComputedStyle, nullptr);
|
2004-01-28 03:18:22 +03:00
|
|
|
|
2018-03-22 21:20:41 +03:00
|
|
|
aMathMLChar->SetComputedStyle(newComputedStyle);
|
2002-02-07 07:38:08 +03:00
|
|
|
}
|
2002-01-09 21:51:30 +03:00
|
|
|
|
2002-02-07 07:38:08 +03:00
|
|
|
/* static */ void nsMathMLFrame::GetEmbellishDataFrom(
|
|
|
|
nsIFrame* aFrame, nsEmbellishData& aEmbellishData) {
|
|
|
|
// initialize OUT params
|
|
|
|
aEmbellishData.flags = 0;
|
2012-07-30 18:20:58 +04:00
|
|
|
aEmbellishData.coreFrame = nullptr;
|
2002-02-07 07:38:08 +03:00
|
|
|
aEmbellishData.direction = NS_STRETCH_DIRECTION_UNSUPPORTED;
|
2011-12-22 02:21:59 +04:00
|
|
|
aEmbellishData.leadingSpace = 0;
|
|
|
|
aEmbellishData.trailingSpace = 0;
|
2002-02-07 07:38:08 +03:00
|
|
|
|
2006-08-15 08:49:43 +04:00
|
|
|
if (aFrame && aFrame->IsFrameOfType(nsIFrame::eMathML)) {
|
2009-01-12 22:20:59 +03:00
|
|
|
nsIMathMLFrame* mathMLFrame = do_QueryFrame(aFrame);
|
2002-02-07 07:38:08 +03:00
|
|
|
if (mathMLFrame) {
|
|
|
|
mathMLFrame->GetEmbellishData(aEmbellishData);
|
|
|
|
}
|
|
|
|
}
|
2002-01-09 21:51:30 +03:00
|
|
|
}
|
|
|
|
|
2002-01-12 11:06:08 +03:00
|
|
|
// helper to get the presentation data of a frame, by possibly walking up
|
|
|
|
// the frame hierarchy if we happen to be surrounded by non-MathML frames.
|
|
|
|
/* static */ void nsMathMLFrame::GetPresentationDataFrom(
|
2002-02-07 07:38:08 +03:00
|
|
|
nsIFrame* aFrame, nsPresentationData& aPresentationData, bool aClimbTree) {
|
|
|
|
// initialize OUT params
|
|
|
|
aPresentationData.flags = 0;
|
2012-07-30 18:20:58 +04:00
|
|
|
aPresentationData.baseFrame = nullptr;
|
2002-02-07 07:38:08 +03:00
|
|
|
|
2002-01-12 11:06:08 +03:00
|
|
|
nsIFrame* frame = aFrame;
|
|
|
|
while (frame) {
|
2006-08-15 08:49:43 +04:00
|
|
|
if (frame->IsFrameOfType(nsIFrame::eMathML)) {
|
2009-01-12 22:20:59 +03:00
|
|
|
nsIMathMLFrame* mathMLFrame = do_QueryFrame(frame);
|
2006-08-15 08:49:43 +04:00
|
|
|
if (mathMLFrame) {
|
|
|
|
mathMLFrame->GetPresentationData(aPresentationData);
|
|
|
|
break;
|
|
|
|
}
|
2002-02-07 07:38:08 +03:00
|
|
|
}
|
|
|
|
// stop if the caller doesn't want to lookup beyond the frame
|
|
|
|
if (!aClimbTree) {
|
2002-01-12 11:06:08 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
// stop if we reach the root <math> tag
|
2003-07-08 15:00:00 +04:00
|
|
|
nsIContent* content = frame->GetContent();
|
2008-01-16 08:07:09 +03:00
|
|
|
NS_ASSERTION(content || !frame->GetParent(), // no assert for the root
|
2017-07-06 15:00:35 +03:00
|
|
|
"dangling frame without a content node");
|
2002-04-02 07:57:56 +04:00
|
|
|
if (!content) break;
|
2003-11-19 04:20:56 +03:00
|
|
|
|
2015-03-03 14:09:00 +03:00
|
|
|
if (content->IsMathMLElement(nsGkAtoms::math)) {
|
2002-01-12 11:06:08 +03:00
|
|
|
break;
|
|
|
|
}
|
2003-07-08 15:00:00 +04:00
|
|
|
frame = frame->GetParent();
|
2002-01-12 11:06:08 +03:00
|
|
|
}
|
2016-09-01 08:01:16 +03:00
|
|
|
NS_WARNING_ASSERTION(
|
|
|
|
frame && frame->GetContent(),
|
|
|
|
"bad MathML markup - could not find the top <math> element");
|
2002-01-12 11:06:08 +03:00
|
|
|
}
|
|
|
|
|
2015-12-16 00:56:41 +03:00
|
|
|
/* static */ void nsMathMLFrame::GetRuleThickness(DrawTarget* aDrawTarget,
|
|
|
|
nsFontMetrics* aFontMetrics,
|
|
|
|
nscoord& aRuleThickness) {
|
2011-04-08 08:18:43 +04:00
|
|
|
nscoord xHeight = aFontMetrics->XHeight();
|
2014-01-04 19:02:17 +04:00
|
|
|
char16_t overBar = 0x00AF;
|
2014-10-24 19:28:14 +04:00
|
|
|
nsBoundingMetrics bm = nsLayoutUtils::AppUnitBoundsOfString(
|
|
|
|
&overBar, 1, *aFontMetrics, aDrawTarget);
|
2011-04-08 05:04:40 +04:00
|
|
|
aRuleThickness = bm.ascent + bm.descent;
|
|
|
|
if (aRuleThickness <= 0 || aRuleThickness >= xHeight) {
|
2002-01-09 21:51:30 +03:00
|
|
|
// fall-back to the other version
|
|
|
|
GetRuleThickness(aFontMetrics, aRuleThickness);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-16 00:56:41 +03:00
|
|
|
/* static */ void nsMathMLFrame::GetAxisHeight(DrawTarget* aDrawTarget,
|
|
|
|
nsFontMetrics* aFontMetrics,
|
|
|
|
nscoord& aAxisHeight) {
|
2014-07-02 07:29:00 +04:00
|
|
|
gfxFont* mathFont = aFontMetrics->GetThebesFontGroup()->GetFirstMathFont();
|
|
|
|
if (mathFont) {
|
2016-11-02 21:47:18 +03:00
|
|
|
aAxisHeight = mathFont->MathTable()->Constant(
|
|
|
|
gfxMathTable::AxisHeight, aFontMetrics->AppUnitsPerDevPixel());
|
2014-07-02 07:29:00 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2011-04-08 08:18:43 +04:00
|
|
|
nscoord xHeight = aFontMetrics->XHeight();
|
2014-01-04 19:02:17 +04:00
|
|
|
char16_t minus = 0x2212; // not '-', but official Unicode minus sign
|
2015-12-16 00:56:41 +03:00
|
|
|
nsBoundingMetrics bm = nsLayoutUtils::AppUnitBoundsOfString(
|
|
|
|
&minus, 1, *aFontMetrics, aDrawTarget);
|
2011-04-08 05:04:40 +04:00
|
|
|
aAxisHeight = bm.ascent - (bm.ascent + bm.descent) / 2;
|
|
|
|
if (aAxisHeight <= 0 || aAxisHeight >= xHeight) {
|
2002-01-09 21:51:30 +03:00
|
|
|
// fall-back to the other version
|
|
|
|
GetAxisHeight(aFontMetrics, aAxisHeight);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-08-01 03:15:21 +04:00
|
|
|
/* static */ nscoord nsMathMLFrame::CalcLength(nsPresContext* aPresContext,
|
2018-03-22 21:20:41 +03:00
|
|
|
ComputedStyle* aComputedStyle,
|
2014-10-25 10:29:00 +04:00
|
|
|
const nsCSSValue& aCSSValue,
|
|
|
|
float aFontSizeInflation) {
|
2002-01-09 21:51:30 +03:00
|
|
|
NS_ASSERTION(aCSSValue.IsLengthUnit(), "not a length unit");
|
|
|
|
|
2010-08-13 13:58:01 +04:00
|
|
|
if (aCSSValue.IsPixelLengthUnit()) {
|
|
|
|
return aCSSValue.GetPixelLength();
|
2002-01-09 21:51:30 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
nsCSSUnit unit = aCSSValue.GetUnit();
|
|
|
|
|
2010-08-13 13:58:01 +04:00
|
|
|
if (eCSSUnit_EM == unit) {
|
2018-03-22 21:20:41 +03:00
|
|
|
const nsStyleFont* font = aComputedStyle->StyleFont();
|
2002-01-09 21:51:30 +03:00
|
|
|
return NSToCoordRound(aCSSValue.GetFloatValue() * (float)font->mFont.size);
|
|
|
|
} else if (eCSSUnit_XHeight == unit) {
|
2015-03-06 11:44:14 +03:00
|
|
|
aPresContext->SetUsesExChUnits(true);
|
2016-03-17 08:55:48 +03:00
|
|
|
RefPtr<nsFontMetrics> fm = nsLayoutUtils::GetFontMetricsForComputedStyle(
|
2018-04-06 15:52:12 +03:00
|
|
|
aComputedStyle, aPresContext, aFontSizeInflation);
|
2011-04-08 08:18:43 +04:00
|
|
|
nscoord xHeight = fm->XHeight();
|
2002-01-09 21:51:30 +03:00
|
|
|
return NSToCoordRound(aCSSValue.GetFloatValue() * (float)xHeight);
|
|
|
|
}
|
|
|
|
|
2010-08-13 13:58:01 +04:00
|
|
|
// MathML doesn't specify other CSS units such as rem or ch
|
|
|
|
NS_ERROR("Unsupported unit");
|
2002-01-09 21:51:30 +03:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-05-16 02:30:14 +04:00
|
|
|
/* static */ void nsMathMLFrame::ParseNumericValue(
|
|
|
|
const nsString& aString, nscoord* aLengthValue, uint32_t aFlags,
|
2018-03-22 21:20:41 +03:00
|
|
|
nsPresContext* aPresContext, ComputedStyle* aComputedStyle,
|
2014-10-25 10:29:00 +04:00
|
|
|
float aFontSizeInflation) {
|
2012-05-16 02:30:14 +04:00
|
|
|
nsCSSValue cssValue;
|
|
|
|
|
2012-12-27 20:12:05 +04:00
|
|
|
if (!nsMathMLElement::ParseNumericValue(aString, cssValue, aFlags,
|
|
|
|
aPresContext->Document())) {
|
2012-05-16 02:30:14 +04:00
|
|
|
// Invalid attribute value. aLengthValue remains unchanged, so the default
|
|
|
|
// length value is used.
|
|
|
|
return;
|
2011-06-22 19:55:05 +04:00
|
|
|
}
|
2002-01-09 21:51:30 +03:00
|
|
|
|
2012-05-16 02:30:14 +04:00
|
|
|
nsCSSUnit unit = cssValue.GetUnit();
|
2002-01-09 21:51:30 +03:00
|
|
|
|
2012-05-16 02:30:14 +04:00
|
|
|
if (unit == eCSSUnit_Percent || unit == eCSSUnit_Number) {
|
|
|
|
// Relative units. A multiple of the default length value is used.
|
|
|
|
*aLengthValue = NSToCoordRound(
|
|
|
|
*aLengthValue * (unit == eCSSUnit_Percent ? cssValue.GetPercentValue()
|
|
|
|
: cssValue.GetFloatValue()));
|
|
|
|
return;
|
2002-01-09 21:51:30 +03:00
|
|
|
}
|
2017-07-06 15:00:35 +03:00
|
|
|
|
2012-05-16 02:30:14 +04:00
|
|
|
// Absolute units.
|
2018-03-22 21:20:41 +03:00
|
|
|
*aLengthValue =
|
|
|
|
CalcLength(aPresContext, aComputedStyle, cssValue, aFontSizeInflation);
|
2002-01-09 21:51:30 +03:00
|
|
|
}
|
2002-02-14 15:26:43 +03:00
|
|
|
|
2012-06-25 23:59:42 +04:00
|
|
|
#if defined(DEBUG) && defined(SHOW_BOUNDING_BOX)
|
2018-09-06 04:23:14 +03:00
|
|
|
class nsDisplayMathMLBoundingMetrics final : public nsDisplayItem {
|
2006-01-26 05:29:17 +03:00
|
|
|
public:
|
2010-08-13 14:01:13 +04:00
|
|
|
nsDisplayMathMLBoundingMetrics(nsDisplayListBuilder* aBuilder,
|
|
|
|
nsIFrame* aFrame, const nsRect& aRect)
|
|
|
|
: nsDisplayItem(aBuilder, aFrame), mRect(aRect) {
|
2006-01-29 21:48:58 +03:00
|
|
|
MOZ_COUNT_CTOR(nsDisplayMathMLBoundingMetrics);
|
|
|
|
}
|
|
|
|
#ifdef NS_BUILD_REFCNT_LOGGING
|
|
|
|
virtual ~nsDisplayMathMLBoundingMetrics() {
|
|
|
|
MOZ_COUNT_DTOR(nsDisplayMathMLBoundingMetrics);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2009-09-07 04:35:14 +04:00
|
|
|
virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
|
2010-07-16 01:07:49 +04:00
|
|
|
NS_DISPLAY_DECL_NAME("MathMLBoundingMetrics", TYPE_MATHML_BOUNDING_METRICS)
|
2006-01-26 05:29:17 +03:00
|
|
|
private:
|
|
|
|
nsRect mRect;
|
|
|
|
};
|
|
|
|
|
|
|
|
void nsDisplayMathMLBoundingMetrics::Paint(nsDisplayListBuilder* aBuilder,
|
2017-06-09 22:14:53 +03:00
|
|
|
gfxContext* aCtx) {
|
2016-03-31 05:04:00 +03:00
|
|
|
DrawTarget* drawTarget = aCtx->GetDrawTarget();
|
2014-10-17 18:06:34 +04:00
|
|
|
Rect r = NSRectToRect(mRect + ToReferenceFrame(),
|
|
|
|
mFrame->PresContext()->AppUnitsPerDevPixel());
|
|
|
|
ColorPattern blue(ToDeviceColor(Color(0.f, 0.f, 1.f, 1.f)));
|
|
|
|
drawTarget->StrokeRect(r, blue);
|
2006-01-26 05:29:17 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void nsMathMLFrame::DisplayBoundingMetrics(nsDisplayListBuilder* aBuilder,
|
|
|
|
nsIFrame* aFrame, const nsPoint& aPt,
|
|
|
|
const nsBoundingMetrics& aMetrics,
|
|
|
|
const nsDisplayListSet& aLists) {
|
|
|
|
if (!NS_MATHML_PAINT_BOUNDING_METRICS(mPresentationData.flags)) return;
|
2017-07-06 15:00:35 +03:00
|
|
|
|
2006-01-26 05:29:17 +03:00
|
|
|
nscoord x = aPt.x + aMetrics.leftBearing;
|
|
|
|
nscoord y = aPt.y - aMetrics.ascent;
|
|
|
|
nscoord w = aMetrics.rightBearing - aMetrics.leftBearing;
|
|
|
|
nscoord h = aMetrics.ascent + aMetrics.descent;
|
|
|
|
|
2018-02-13 03:43:28 +03:00
|
|
|
aLists.Content()->AppendToTop(MakeDisplayItem<nsDisplayMathMLBoundingMetrics>(
|
|
|
|
aBuilder, aFrame, nsRect(x, y, w, h)));
|
2006-01-26 05:29:17 +03:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2018-09-06 04:23:14 +03:00
|
|
|
class nsDisplayMathMLBar final : public nsDisplayItem {
|
2006-01-26 05:29:17 +03:00
|
|
|
public:
|
2010-08-13 14:01:13 +04:00
|
|
|
nsDisplayMathMLBar(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
|
2017-08-10 14:26:42 +03:00
|
|
|
const nsRect& aRect, uint32_t aIndex)
|
|
|
|
: nsDisplayItem(aBuilder, aFrame), mRect(aRect), mIndex(aIndex) {
|
2006-01-29 21:48:58 +03:00
|
|
|
MOZ_COUNT_CTOR(nsDisplayMathMLBar);
|
|
|
|
}
|
|
|
|
#ifdef NS_BUILD_REFCNT_LOGGING
|
|
|
|
virtual ~nsDisplayMathMLBar() { MOZ_COUNT_DTOR(nsDisplayMathMLBar); }
|
|
|
|
#endif
|
|
|
|
|
2017-08-24 18:09:44 +03:00
|
|
|
virtual uint32_t GetPerFrameKey() const override {
|
2017-08-10 14:26:42 +03:00
|
|
|
return (mIndex << TYPE_BITS) | nsDisplayItem::GetPerFrameKey();
|
|
|
|
}
|
|
|
|
|
2009-09-07 04:35:14 +04:00
|
|
|
virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
|
2010-07-16 01:07:49 +04:00
|
|
|
NS_DISPLAY_DECL_NAME("MathMLBar", TYPE_MATHML_BAR)
|
2006-01-26 05:29:17 +03:00
|
|
|
private:
|
|
|
|
nsRect mRect;
|
2017-08-10 14:26:42 +03:00
|
|
|
uint32_t mIndex;
|
2006-01-26 05:29:17 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
void nsDisplayMathMLBar::Paint(nsDisplayListBuilder* aBuilder,
|
2017-06-09 22:14:53 +03:00
|
|
|
gfxContext* aCtx) {
|
2006-01-26 05:29:17 +03:00
|
|
|
// paint the bar with the current text color
|
2014-10-19 16:22:22 +04:00
|
|
|
DrawTarget* drawTarget = aCtx->GetDrawTarget();
|
2015-10-17 20:18:00 +03:00
|
|
|
Rect rect = NSRectToNonEmptySnappedRect(
|
|
|
|
mRect + ToReferenceFrame(), mFrame->PresContext()->AppUnitsPerDevPixel(),
|
|
|
|
*drawTarget);
|
2014-10-19 16:22:22 +04:00
|
|
|
ColorPattern color(ToDeviceColor(
|
2016-12-30 16:57:37 +03:00
|
|
|
mFrame->GetVisitedDependentColor(&nsStyleText::mWebkitTextFillColor)));
|
2014-10-19 16:22:22 +04:00
|
|
|
drawTarget->FillRect(rect, color);
|
2006-01-26 05:29:17 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void nsMathMLFrame::DisplayBar(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
|
|
|
|
const nsRect& aRect,
|
2017-08-10 14:26:42 +03:00
|
|
|
const nsDisplayListSet& aLists,
|
|
|
|
uint32_t aIndex) {
|
2013-02-17 01:51:02 +04:00
|
|
|
if (!aFrame->StyleVisibility()->IsVisible() || aRect.IsEmpty()) return;
|
2006-01-26 05:29:17 +03:00
|
|
|
|
2018-02-13 03:43:28 +03:00
|
|
|
aLists.Content()->AppendToTop(
|
|
|
|
MakeDisplayItem<nsDisplayMathMLBar>(aBuilder, aFrame, aRect, aIndex));
|
2006-01-26 05:29:17 +03:00
|
|
|
}
|
2014-06-17 10:40:00 +04:00
|
|
|
|
|
|
|
void nsMathMLFrame::GetRadicalParameters(nsFontMetrics* aFontMetrics,
|
|
|
|
bool aDisplayStyle,
|
|
|
|
nscoord& aRadicalRuleThickness,
|
|
|
|
nscoord& aRadicalExtraAscender,
|
|
|
|
nscoord& aRadicalVerticalGap) {
|
|
|
|
nscoord oneDevPixel = aFontMetrics->AppUnitsPerDevPixel();
|
|
|
|
gfxFont* mathFont = aFontMetrics->GetThebesFontGroup()->GetFirstMathFont();
|
|
|
|
|
|
|
|
// get the radical rulethickness
|
|
|
|
if (mathFont) {
|
2016-11-02 21:47:18 +03:00
|
|
|
aRadicalRuleThickness = mathFont->MathTable()->Constant(
|
|
|
|
gfxMathTable::RadicalRuleThickness, oneDevPixel);
|
2014-06-17 10:40:00 +04:00
|
|
|
} else {
|
|
|
|
GetRuleThickness(aFontMetrics, aRadicalRuleThickness);
|
|
|
|
}
|
|
|
|
|
|
|
|
// get the leading to be left at the top of the resulting frame
|
|
|
|
if (mathFont) {
|
2016-11-02 21:47:18 +03:00
|
|
|
aRadicalExtraAscender = mathFont->MathTable()->Constant(
|
|
|
|
gfxMathTable::RadicalExtraAscender, oneDevPixel);
|
2014-06-17 10:40:00 +04:00
|
|
|
} else {
|
|
|
|
// This seems more reliable than using aFontMetrics->GetLeading() on
|
|
|
|
// suspicious fonts.
|
|
|
|
nscoord em;
|
|
|
|
GetEmHeight(aFontMetrics, em);
|
|
|
|
aRadicalExtraAscender = nscoord(0.2f * em);
|
|
|
|
}
|
|
|
|
|
|
|
|
// get the clearance between rule and content
|
|
|
|
if (mathFont) {
|
2016-11-02 21:47:18 +03:00
|
|
|
aRadicalVerticalGap = mathFont->MathTable()->Constant(
|
|
|
|
aDisplayStyle ? gfxMathTable::RadicalDisplayStyleVerticalGap
|
|
|
|
: gfxMathTable::RadicalVerticalGap,
|
|
|
|
oneDevPixel);
|
2014-06-17 10:40:00 +04:00
|
|
|
} else {
|
|
|
|
// Rule 11, App. G, TeXbook
|
|
|
|
aRadicalVerticalGap =
|
|
|
|
aRadicalRuleThickness +
|
|
|
|
(aDisplayStyle ? aFontMetrics->XHeight() : aRadicalRuleThickness) / 4;
|
|
|
|
}
|
|
|
|
}
|