PRBool nsSVGGeometryFrame::SetupCairoFill(gfxContext *aContext) { const nsStyleSVG* style = GetStyleSVG(); if (style->mFill.mType == eStyleSVGPaintType_None) return PR_FALSE; if (style->mFillRule == NS_STYLE_FILL_RULE_EVENODD) aContext->SetFillRule(gfxContext::FILL_RULE_EVEN_ODD); else aContext->SetFillRule(gfxContext::FILL_RULE_WINDING); float opacity = MaybeOptimizeOpacity(style->mFillOpacity); nsSVGPaintServerFrame *ps = GetPaintServer(&style->mFill, nsSVGEffects::FillProperty()); if (ps && ps->SetupPaintServer(aContext, this, opacity)) return PR_TRUE; // On failure, use the fallback colour in case we have an // objectBoundingBox where the width or height of the object is zero. // See http://www.w3.org/TR/SVG11/coords.html#ObjectBoundingBox SetupFallbackOrPaintColor(aContext, GetStyleContext(), &nsStyleSVG::mFill, opacity); return PR_TRUE; }
nsresult nsProgressFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements) { // Get the NodeInfoManager and tag necessary to create the progress bar div. nsCOMPtr<nsIDocument> doc = mContent->GetDocument(); nsCOMPtr<nsINodeInfo> nodeInfo; nodeInfo = doc->NodeInfoManager()->GetNodeInfo(nsGkAtoms::div, nsnull, kNameSpaceID_XHTML, nsIDOMNode::ELEMENT_NODE); NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY); // Create the div. nsresult rv = NS_NewHTMLElement(getter_AddRefs(mBarDiv), nodeInfo.forget(), mozilla::dom::NOT_FROM_PARSER); NS_ENSURE_SUCCESS(rv, rv); // Associate ::-moz-progress-bar pseudo-element to the anonymous child. nsCSSPseudoElements::Type pseudoType = nsCSSPseudoElements::ePseudo_mozProgressBar; nsRefPtr<nsStyleContext> newStyleContext = PresContext()->StyleSet()-> ResolvePseudoElementStyle(mContent->AsElement(), pseudoType, GetStyleContext()); if (!aElements.AppendElement(ContentInfo(mBarDiv, newStyleContext))) { return NS_ERROR_OUT_OF_MEMORY; } return NS_OK; }
nscoord nsTextControlFrame::GetBoxAscent(nsBoxLayoutState& aState) { // Return the baseline of the first (nominal) row, with centering for // single-line controls. // First calculate the ascent wrt the client rect nsRect clientRect; GetClientRect(clientRect); nscoord lineHeight = IsSingleLineTextControl() ? clientRect.height : nsHTMLReflowState::CalcLineHeight(GetStyleContext(), NS_AUTOHEIGHT); nsRefPtr<nsFontMetrics> fontMet; nsresult rv = nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fontMet)); NS_ENSURE_SUCCESS(rv, 0); nscoord ascent = nsLayoutUtils::GetCenteredFontBaseline(fontMet, lineHeight); // Now adjust for our borders and padding ascent += clientRect.y; return ascent; }
NS_IMETHODIMP nsTableCaptionFrame::GetParentStyleContextFrame(nsPresContext* aPresContext, nsIFrame** aProviderFrame, PRBool* aIsChild) { NS_PRECONDITION(mContent->GetParent(), "How could we not have a parent here?"); // The caption's style context parent is the inner frame, unless // it's anonymous. nsIFrame* outerFrame = GetParent(); if (outerFrame && outerFrame->GetType() == nsGkAtoms::tableOuterFrame) { nsIFrame* innerFrame = outerFrame->GetFirstChild(nsnull); if (innerFrame) { *aProviderFrame = nsFrame::CorrectStyleParentFrame(innerFrame, GetStyleContext()->GetPseudo()); *aIsChild = PR_FALSE; return NS_OK; } } NS_NOTREACHED("Where is our inner table frame?"); return nsBlockFrame::GetParentStyleContextFrame(aPresContext, aProviderFrame, aIsChild); }
nsRect nsInlineFrame::ComputeTightBounds(gfxContext* aContext) const { // be conservative if (GetStyleContext()->HasTextDecorations()) return GetOverflowRect(); return ComputeSimpleTightBounds(aContext); }
nsRect nsTextFrame::ComputeTightBounds(gfxContext* aContext) const { if ((GetStyleContext()->HasTextDecorations() && eCompatibility_NavQuirks == PresContext()->CompatibilityMode()) || (GetStateBits() & (nsFrameState(1) << (23)))) return GetOverflowRect(); gfxSkipCharsIterator iter = const_cast<nsTextFrame*>(this)->EnsureTextRun(); PropertyProvider provider(const_cast<nsTextFrame*>(this), iter); }
NS_IMETHODIMP nsTitleBarFrame::Init(nsIContent* aContent, nsIFrame* aParent, nsIFrame* asPrevInFlow) { nsresult rv = nsBoxFrame::Init(aContent, aParent, asPrevInFlow); CreateViewForFrame(PresContext(), this, GetStyleContext(), PR_TRUE); return rv; }
/* virtual */ void nsTableColFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext) { if (!aOldStyleContext) //avoid this on init return; nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this); if (tableFrame->IsBorderCollapse() && tableFrame->BCRecalcNeeded(aOldStyleContext, GetStyleContext())) { nsIntRect damageArea(GetColIndex(), 0, 1, tableFrame->GetRowCount()); tableFrame->AddBCDamageArea(damageArea); } }
/* virtual */ void nsTableColGroupFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext) { if (!aOldStyleContext) //avoid this on init return; nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this); if (tableFrame->IsBorderCollapse() && tableFrame->BCRecalcNeeded(aOldStyleContext, GetStyleContext())) { PRInt32 colCount = GetColCount(); if (!colCount) return; // this is a degenerated colgroup nsIntRect damageArea(GetFirstColumn()->GetColIndex(), 0, colCount, tableFrame->GetRowCount()); tableFrame->AddBCDamageArea(damageArea); } }
PRInt32 nsMathMLmtdFrame::GetColSpan() { PRInt32 colspan = 1; // Don't look at the content's colspan if we're not an mtd or a pseudo cell. if ((mContent->Tag() == nsGkAtoms::mtd_) && !GetStyleContext()->GetPseudoType()) { nsAutoString value; mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::columnspan_, value); if (!value.IsEmpty()) { PRInt32 error; colspan = value.ToInteger(&error); if (error || colspan < 0 || colspan > MAX_COLSPAN) colspan = 1; } } return colspan; }
PRInt32 nsMathMLmtdFrame::GetRowSpan() { PRInt32 rowspan = 1; // Don't look at the content's rowspan if we're not an mtd or a pseudo cell. if ((mContent->Tag() == nsGkAtoms::mtd_) && !GetStyleContext()->GetPseudoType()) { nsAutoString value; mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::rowspan, value); if (!value.IsEmpty()) { PRInt32 error; rowspan = value.ToInteger(&error); if (error || rowspan < 0) rowspan = 1; rowspan = PR_MIN(rowspan, MAX_ROWSPAN); } } return rowspan; }
/** * Initialize us. If we are in a box get our alignment so we know what direction we are */ NS_IMETHODIMP nsSplitterFrame::Init(nsIContent* aContent, nsIFrame* aParent, nsIFrame* aPrevInFlow) { NS_ENSURE_FALSE(mInner, NS_ERROR_ALREADY_INITIALIZED); mInner = new nsSplitterFrameInner(this); if (!mInner) return NS_ERROR_OUT_OF_MEMORY; mInner->AddRef(); mInner->mChildInfosAfter = nullptr; mInner->mChildInfosBefore = nullptr; mInner->mState = nsSplitterFrameInner::Open; mInner->mDragging = false; // determine orientation of parent, and if vertical, set orient to vertical // on splitter content, then re-resolve style // XXXbz this is pretty messed up, since this can change whether we should // have a frame at all. This really needs a better solution. if (aParent && aParent->IsBoxFrame()) { if (!aParent->IsHorizontal()) { if (!nsContentUtils::HasNonEmptyAttr(aContent, kNameSpaceID_None, nsGkAtoms::orient)) { aContent->SetAttr(kNameSpaceID_None, nsGkAtoms::orient, NS_LITERAL_STRING("vertical"), false); nsStyleContext* parentStyleContext = GetStyleContext()->GetParent(); nsRefPtr<nsStyleContext> newContext = PresContext()->StyleSet()-> ResolveStyleFor(aContent->AsElement(), parentStyleContext); SetStyleContextWithoutNotification(newContext); } } } nsresult rv = nsBoxFrame::Init(aContent, aParent, aPrevInFlow); NS_ENSURE_SUCCESS(rv, rv); mInner->mState = nsSplitterFrameInner::Open; mInner->AddListener(PresContext()); mInner->mParentBox = nullptr; return rv; }
nsIFrame* nsTableCaptionFrame::GetParentStyleContextFrame() { NS_PRECONDITION(mContent->GetParent(), "How could we not have a parent here?"); // The caption's style context parent is the inner frame, unless // it's anonymous. nsIFrame* outerFrame = GetParent(); if (outerFrame && outerFrame->GetType() == nsGkAtoms::tableOuterFrame) { nsIFrame* innerFrame = outerFrame->GetFirstPrincipalChild(); if (innerFrame) { return nsFrame::CorrectStyleParentFrame(innerFrame, GetStyleContext()->GetPseudo()); } } NS_NOTREACHED("Where is our inner table frame?"); return nsBlockFrame::GetParentStyleContextFrame(); }
PRBool nsSVGGeometryFrame::SetupCairoStroke(gfxContext *aContext) { if (!HasStroke()) { return PR_FALSE; } SetupCairoStrokeHitGeometry(aContext); const nsStyleSVG* style = GetStyleSVG(); float opacity = MaybeOptimizeOpacity(style->mStrokeOpacity); nsSVGPaintServerFrame *ps = GetPaintServer(&style->mStroke, nsSVGEffects::StrokeProperty()); if (ps && ps->SetupPaintServer(aContext, this, opacity)) return PR_TRUE; // On failure, use the fallback colour in case we have an // objectBoundingBox where the width or height of the object is zero. // See http://www.w3.org/TR/SVG11/coords.html#ObjectBoundingBox SetupFallbackOrPaintColor(aContext, GetStyleContext(), &nsStyleSVG::mStroke, opacity); return PR_TRUE; }
nsresult nsTextControlFrame::CalcIntrinsicSize(nsRenderingContext* aRenderingContext, nsSize& aIntrinsicSize) { // Get leading and the Average/MaxAdvance char width nscoord lineHeight = 0; nscoord charWidth = 0; nscoord charMaxAdvance = 0; nsRefPtr<nsFontMetrics> fontMet; nsresult rv = nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fontMet)); NS_ENSURE_SUCCESS(rv, rv); aRenderingContext->SetFont(fontMet); lineHeight = nsHTMLReflowState::CalcLineHeight(GetStyleContext(), NS_AUTOHEIGHT); charWidth = fontMet->AveCharWidth(); charMaxAdvance = fontMet->MaxAdvance(); // Set the width equal to the width in characters PRInt32 cols = GetCols(); aIntrinsicSize.width = cols * charWidth; // To better match IE, take the maximum character width(in twips) and remove // 4 pixels add this on as additional padding(internalPadding). But only do // this if charMaxAdvance != charWidth; if they are equal, this is almost // certainly a fixed-width font. if (charWidth != charMaxAdvance) { nscoord internalPadding = NS_MAX(0, charMaxAdvance - nsPresContext::CSSPixelsToAppUnits(4)); nscoord t = nsPresContext::CSSPixelsToAppUnits(1); // Round to a multiple of t nscoord rest = internalPadding % t; if (rest < t - rest) { internalPadding -= rest; } else { internalPadding += t - rest; } // Now add the extra padding on (so that small input sizes work well) aIntrinsicSize.width += internalPadding; } else { // This is to account for the anonymous <br> having a 1 twip width // in Full Standards mode, see BRFrame::Reflow and bug 228752. if (PresContext()->CompatibilityMode() == eCompatibility_FullStandards) { aIntrinsicSize.width += 1; } // Also add in the padding of our value div child. Note that it hasn't // been reflowed yet, so we can't get its used padding, but it shouldn't be // using percentage padding anyway. nsMargin childPadding; nsIFrame* firstChild = GetFirstChild(nsnull); if (firstChild && firstChild->GetStylePadding()->GetPadding(childPadding)) { aIntrinsicSize.width += childPadding.LeftRight(); } else { NS_ERROR("Percentage padding on value div?"); } } // Increment width with cols * letter-spacing. { const nsStyleCoord& lsCoord = GetStyleText()->mLetterSpacing; if (eStyleUnit_Coord == lsCoord.GetUnit()) { nscoord letterSpacing = lsCoord.GetCoordValue(); if (letterSpacing != 0) { aIntrinsicSize.width += cols * letterSpacing; } } } // Set the height equal to total number of rows (times the height of each // line, of course) aIntrinsicSize.height = lineHeight * GetRows(); // Add in the size of the scrollbars for textarea if (IsTextArea()) { nsIFrame* first = GetFirstChild(nsnull); nsIScrollableFrame *scrollableFrame = do_QueryFrame(first); NS_ASSERTION(scrollableFrame, "Child must be scrollable"); if (scrollableFrame) { nsMargin scrollbarSizes = scrollableFrame->GetDesiredScrollbarSizes(PresContext(), aRenderingContext); aIntrinsicSize.width += scrollbarSizes.LeftRight(); aIntrinsicSize.height += scrollbarSizes.TopBottom();; } } return NS_OK; }
void nsTextBoxFrame::CalculateTitleForWidth(nsPresContext* aPresContext, nsIRenderingContext& aRenderingContext, nscoord aWidth) { if (mTitle.IsEmpty()) return; nsLayoutUtils::SetFontFromStyle(&aRenderingContext, GetStyleContext()); // see if the text will completely fit in the width given mTitleWidth = nsLayoutUtils::GetStringWidth(this, &aRenderingContext, mTitle.get(), mTitle.Length()); if (mTitleWidth <= aWidth) { mCroppedTitle = mTitle; #ifdef IBMBIDI if (HasRTLChars(mTitle)) { mState |= NS_FRAME_IS_BIDI; } #endif // IBMBIDI return; // fits, done. } const nsDependentString& kEllipsis = nsContentUtils::GetLocalizedEllipsis(); // start with an ellipsis mCroppedTitle.Assign(kEllipsis); // see if the width is even smaller than the ellipsis // if so, clear the text (XXX set as many '.' as we can?). aRenderingContext.SetTextRunRTL(PR_FALSE); aRenderingContext.GetWidth(kEllipsis, mTitleWidth); if (mTitleWidth > aWidth) { mCroppedTitle.SetLength(0); mTitleWidth = 0; return; } // if the ellipsis fits perfectly, no use in trying to insert if (mTitleWidth == aWidth) return; aWidth -= mTitleWidth; // XXX: This whole block should probably take surrogates into account // XXX and clusters! // ok crop things switch (mCropType) { case CropNone: case CropRight: { nscoord cwidth; nscoord twidth = 0; int length = mTitle.Length(); int i; for (i = 0; i < length; ++i) { PRUnichar ch = mTitle.CharAt(i); // still in LTR mode aRenderingContext.GetWidth(ch,cwidth); if (twidth + cwidth > aWidth) break; twidth += cwidth; #ifdef IBMBIDI if (UCS2_CHAR_IS_BIDI(ch) ) { mState |= NS_FRAME_IS_BIDI; } #endif // IBMBIDI } if (i == 0) return; // insert what character we can in. nsAutoString title( mTitle ); title.Truncate(i); mCroppedTitle.Insert(title, 0); } break; case CropLeft: { nscoord cwidth; nscoord twidth = 0; int length = mTitle.Length(); int i; for (i=length-1; i >= 0; --i) { PRUnichar ch = mTitle.CharAt(i); aRenderingContext.GetWidth(ch,cwidth); if (twidth + cwidth > aWidth) break; twidth += cwidth; #ifdef IBMBIDI if (UCS2_CHAR_IS_BIDI(ch) ) { mState |= NS_FRAME_IS_BIDI; } #endif // IBMBIDI } if (i == length-1) return; nsAutoString copy; mTitle.Right(copy, length-1-i); mCroppedTitle += copy; } break; case CropCenter: { nscoord stringWidth = nsLayoutUtils::GetStringWidth(this, &aRenderingContext, mTitle.get(), mTitle.Length()); if (stringWidth <= aWidth) { // the entire string will fit in the maximum width mCroppedTitle.Insert(mTitle, 0); break; } // determine how much of the string will fit in the max width nscoord charWidth = 0; nscoord totalWidth = 0; PRUnichar ch; int leftPos, rightPos; nsAutoString leftString, rightString; rightPos = mTitle.Length() - 1; aRenderingContext.SetTextRunRTL(PR_FALSE); for (leftPos = 0; leftPos <= rightPos;) { // look at the next character on the left end ch = mTitle.CharAt(leftPos); aRenderingContext.GetWidth(ch, charWidth); totalWidth += charWidth; if (totalWidth > aWidth) // greater than the allowable width break; leftString.Insert(ch, leftString.Length()); #ifdef IBMBIDI if (UCS2_CHAR_IS_BIDI(ch)) mState |= NS_FRAME_IS_BIDI; #endif // look at the next character on the right end if (rightPos > leftPos) { // haven't looked at this character yet ch = mTitle.CharAt(rightPos); aRenderingContext.GetWidth(ch, charWidth); totalWidth += charWidth; if (totalWidth > aWidth) // greater than the allowable width break; rightString.Insert(ch, 0); #ifdef IBMBIDI if (UCS2_CHAR_IS_BIDI(ch)) mState |= NS_FRAME_IS_BIDI; #endif } // look at the next two characters leftPos++; rightPos--; } mCroppedTitle = leftString + kEllipsis + rightString; } break; } mTitleWidth = nsLayoutUtils::GetStringWidth(this, &aRenderingContext, mCroppedTitle.get(), mCroppedTitle.Length()); }
void nsColumnSetFrame::PaintColumnRule(nsRenderingContext* aCtx, const nsRect& aDirtyRect, const nsPoint& aPt) { nsIFrame* child = mFrames.FirstChild(); if (!child) return; // no columns nsIFrame* nextSibling = child->GetNextSibling(); if (!nextSibling) return; // 1 column only - this means no gap to draw on bool isRTL = GetStyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL; const nsStyleColumn* colStyle = GetStyleColumn(); PRUint8 ruleStyle; // Per spec, inset => ridge and outset => groove if (colStyle->mColumnRuleStyle == NS_STYLE_BORDER_STYLE_INSET) ruleStyle = NS_STYLE_BORDER_STYLE_RIDGE; else if (colStyle->mColumnRuleStyle == NS_STYLE_BORDER_STYLE_OUTSET) ruleStyle = NS_STYLE_BORDER_STYLE_GROOVE; else ruleStyle = colStyle->mColumnRuleStyle; nsPresContext* presContext = PresContext(); nscoord ruleWidth = colStyle->GetComputedColumnRuleWidth(); if (!ruleWidth) return; nscolor ruleColor = GetVisitedDependentColor(eCSSProperty__moz_column_rule_color); // In order to re-use a large amount of code, we treat the column rule as a border. // We create a new border style object and fill in all the details of the column rule as // the left border. PaintBorder() does all the rendering for us, so we not // only save an enormous amount of code but we'll support all the line styles that // we support on borders! nsStyleBorder border(presContext); border.SetBorderWidth(NS_SIDE_LEFT, ruleWidth); border.SetBorderStyle(NS_SIDE_LEFT, ruleStyle); border.SetBorderColor(NS_SIDE_LEFT, ruleColor); // Get our content rect as an absolute coordinate, not relative to // our parent (which is what the X and Y normally is) nsRect contentRect = GetContentRect() - GetRect().TopLeft() + aPt; nsSize ruleSize(ruleWidth, contentRect.height); while (nextSibling) { // The frame tree goes RTL in RTL nsIFrame* leftSibling = isRTL ? nextSibling : child; nsIFrame* rightSibling = isRTL ? child : nextSibling; // Each child frame's position coordinates is actually relative to this nsColumnSetFrame. // linePt will be at the top-left edge to paint the line. nsPoint edgeOfLeftSibling = leftSibling->GetRect().TopRight() + aPt; nsPoint edgeOfRightSibling = rightSibling->GetRect().TopLeft() + aPt; nsPoint linePt((edgeOfLeftSibling.x + edgeOfRightSibling.x - ruleWidth) / 2, contentRect.y); nsRect lineRect(linePt, ruleSize); nsCSSRendering::PaintBorderWithStyleBorder(presContext, *aCtx, this, aDirtyRect, lineRect, border, GetStyleContext(), // Remember, we only have the "left" "border". Skip everything else (1 << NS_SIDE_TOP | 1 << NS_SIDE_RIGHT | 1 << NS_SIDE_BOTTOM)); child = nextSibling; nextSibling = nextSibling->GetNextSibling(); } }