NS_IMETHODIMP nsTextBoxFrame::DoLayout(nsBoxLayoutState& aBoxLayoutState) { if (mNeedsReflowCallback) { nsIReflowCallback* cb = new nsAsyncAccesskeyUpdate(this); if (cb) { PresContext()->PresShell()->PostReflowCallback(cb); } mNeedsReflowCallback = PR_FALSE; } mState |= NS_STATE_NEED_LAYOUT; nsresult rv = nsLeafBoxFrame::DoLayout(aBoxLayoutState); const nsStyleText* textStyle = GetStyleText(); if (textStyle->mTextShadow) { nsPoint origin(0,0); nsRect textRect = CalcTextRect(*aBoxLayoutState.GetRenderingContext(), origin); nsRect overflowRect(nsLayoutUtils::GetTextShadowRectsUnion(textRect, this)); overflowRect.UnionRect(overflowRect, nsRect(nsPoint(0, 0), GetSize())); FinishAndStoreOverflow(&overflowRect, GetSize()); } return rv; }
nsSize nsBox::GetMaxSize(nsBoxLayoutState& aState) { NS_ASSERTION(aState.GetRenderingContext(), "must have rendering context"); nsSize maxSize(NS_INTRINSICSIZE, NS_INTRINSICSIZE); DISPLAY_MAX_SIZE(this, maxSize); if (IsCollapsed(aState)) return maxSize; AddBorderAndPadding(maxSize); nsIBox::AddCSSMaxSize(aState, this, maxSize); return maxSize; }
nsSize nsBox::GetMinSize(nsBoxLayoutState& aState) { NS_ASSERTION(aState.GetRenderingContext(), "must have rendering context"); nsSize min(0,0); DISPLAY_MIN_SIZE(this, min); if (IsCollapsed(aState)) return min; AddBorderAndPadding(min); nsIBox::AddCSSMinSize(aState, this, min); return min; }
nsresult nsIFrame::Layout(nsBoxLayoutState& aState) { NS_ASSERTION(aState.GetRenderingContext(), "must have rendering context"); nsBox *box = static_cast<nsBox*>(this); DISPLAY_LAYOUT(box); box->BeginLayout(aState); box->DoLayout(aState); box->EndLayout(aState); return NS_OK; }
void nsTextBoxFrame::CalcTextSize(nsBoxLayoutState& aBoxLayoutState) { if (mNeedsRecalc) { nsSize size; nsPresContext* presContext = aBoxLayoutState.PresContext(); nsIRenderingContext* rendContext = aBoxLayoutState.GetRenderingContext(); if (rendContext) { GetTextSize(presContext, *rendContext, mTitle, size, mAscent); mTextSize = size; mNeedsRecalc = PR_FALSE; } } }
nsSize nsBox::GetXULMaxSize(nsBoxLayoutState& aState) { NS_ASSERTION(aState.GetRenderingContext(), "must have rendering context"); nsSize maxSize(NS_INTRINSICSIZE, NS_INTRINSICSIZE); DISPLAY_MAX_SIZE(this, maxSize); if (IsXULCollapsed()) return maxSize; AddBorderAndPadding(maxSize); bool widthSet, heightSet; nsIFrame::AddXULMaxSize(this, maxSize, widthSet, heightSet); return maxSize; }
nsSize nsBox::GetXULMinSize(nsBoxLayoutState& aState) { NS_ASSERTION(aState.GetRenderingContext(), "must have rendering context"); nsSize min(0,0); DISPLAY_MIN_SIZE(this, min); if (IsXULCollapsed()) return min; AddBorderAndPadding(min); bool widthSet, heightSet; nsIFrame::AddXULMinSize(aState, this, min, widthSet, heightSet); return min; }
nsSize nsBox::GetPrefSize(nsBoxLayoutState& aState) { NS_ASSERTION(aState.GetRenderingContext(), "must have rendering context"); nsSize pref(0,0); DISPLAY_PREF_SIZE(this, pref); if (IsCollapsed(aState)) return pref; AddBorderAndPadding(pref); nsIBox::AddCSSPrefSize(aState, this, pref); nsSize minSize = GetMinSize(aState); nsSize maxSize = GetMaxSize(aState); return BoundsCheck(minSize, pref, maxSize); }
nsSize nsBox::GetXULPrefSize(nsBoxLayoutState& aState) { NS_ASSERTION(aState.GetRenderingContext(), "must have rendering context"); nsSize pref(0,0); DISPLAY_PREF_SIZE(this, pref); if (IsXULCollapsed()) return pref; AddBorderAndPadding(pref); bool widthSet, heightSet; nsIFrame::AddXULPrefSize(this, pref, widthSet, heightSet); nsSize minSize = GetXULMinSize(aState); nsSize maxSize = GetXULMaxSize(aState); return BoundsCheck(minSize, pref, maxSize); }
nsSize nsTextControlFrame::GetPrefSize(nsBoxLayoutState& aState) { if (!DoesNeedRecalc(mPrefSize)) return mPrefSize; #ifdef DEBUG_LAYOUT PropagateDebug(aState); #endif nsSize pref(0,0); // FIXME: This inflation parameter isn't correct; we should fix it if // we want font size inflation to work well in XUL. If we do, we can // also re-enable the assertion in ComputeAutoSize when inflation is // enabled. nsresult rv = CalcIntrinsicSize(aState.GetRenderingContext(), pref, 1.0f); NS_ENSURE_SUCCESS(rv, pref); AddBorderAndPadding(pref); bool widthSet, heightSet; nsIBox::AddCSSPrefSize(this, pref, widthSet, heightSet); nsSize minSize = GetMinSize(aState); nsSize maxSize = GetMaxSize(aState); mPrefSize = BoundsCheck(minSize, pref, maxSize); #ifdef DEBUG_rods { nsMargin borderPadding(0,0,0,0); GetBorderAndPadding(borderPadding); nsSize size(169, 24); nsSize actual(pref.width/15, pref.height/15); printf("nsGfxText(field) %d,%d %d,%d %d,%d\n", size.width, size.height, actual.width, actual.height, actual.width-size.width, actual.height-size.height); // text field } #endif return mPrefSize; }
nsSize nsTextControlFrame::GetPrefSize(nsBoxLayoutState& aState) { if (!DoesNeedRecalc(mPrefSize)) return mPrefSize; #ifdef DEBUG_LAYOUT PropagateDebug(aState); #endif nsSize pref(0,0); nsresult rv = CalcIntrinsicSize(aState.GetRenderingContext(), pref); NS_ENSURE_SUCCESS(rv, pref); AddBorderAndPadding(pref); PRBool widthSet, heightSet; nsIBox::AddCSSPrefSize(this, pref, widthSet, heightSet); nsSize minSize = GetMinSize(aState); nsSize maxSize = GetMaxSize(aState); mPrefSize = BoundsCheck(minSize, pref, maxSize); #ifdef DEBUG_rods { nsMargin borderPadding(0,0,0,0); GetBorderAndPadding(borderPadding); nsSize size(169, 24); nsSize actual(pref.width/15, pref.height/15); printf("nsGfxText(field) %d,%d %d,%d %d,%d\n", size.width, size.height, actual.width, actual.height, actual.width-size.width, actual.height-size.height); // text field } #endif return mPrefSize; }
PRBool nsIBox::AddCSSMinSize(nsBoxLayoutState& aState, nsIBox* aBox, nsSize& aSize, PRBool &aWidthSet, PRBool &aHeightSet) { aWidthSet = PR_FALSE; aHeightSet = PR_FALSE; PRBool canOverride = PR_TRUE; // See if a native theme wants to supply a minimum size. const nsStyleDisplay* display = aBox->GetStyleDisplay(); if (display->mAppearance) { nsITheme *theme = aState.PresContext()->GetTheme(); if (theme && theme->ThemeSupportsWidget(aState.PresContext(), aBox, display->mAppearance)) { nsIntSize size; nsRenderingContext* rendContext = aState.GetRenderingContext(); if (rendContext) { theme->GetMinimumWidgetSize(rendContext, aBox, display->mAppearance, &size, &canOverride); if (size.width) { aSize.width = aState.PresContext()->DevPixelsToAppUnits(size.width); aWidthSet = PR_TRUE; } if (size.height) { aSize.height = aState.PresContext()->DevPixelsToAppUnits(size.height); aHeightSet = PR_TRUE; } } } } // add in the css min, max, pref const nsStylePosition* position = aBox->GetStylePosition(); // same for min size. Unfortunately min size is always set to 0. So for now // we will assume 0 (as a coord) means not set. const nsStyleCoord &minWidth = position->mMinWidth; if ((minWidth.GetUnit() == eStyleUnit_Coord && minWidth.GetCoordValue() != 0) || (minWidth.IsCalcUnit() && !minWidth.CalcHasPercent())) { nscoord min = nsRuleNode::ComputeCoordPercentCalc(minWidth, 0); if (!aWidthSet || (min > aSize.width && canOverride)) { aSize.width = min; aWidthSet = PR_TRUE; } } else if (minWidth.GetUnit() == eStyleUnit_Percent) { NS_ASSERTION(minWidth.GetPercentValue() == 0.0f, "Non-zero percentage values not currently supported"); aSize.width = 0; aWidthSet = PR_TRUE; // FIXME: should we really do this for // nonzero values? } // XXX Handle eStyleUnit_Enumerated? // (Handling the eStyleUnit_Enumerated types requires // GetPrefSize/GetMinSize methods that don't consider // (min-/max-/)(width/height) properties. // calc() with percentage is treated like '0' (unset) const nsStyleCoord &minHeight = position->mMinHeight; if ((minHeight.GetUnit() == eStyleUnit_Coord && minHeight.GetCoordValue() != 0) || (minHeight.IsCalcUnit() && !minHeight.CalcHasPercent())) { nscoord min = nsRuleNode::ComputeCoordPercentCalc(minHeight, 0); if (!aHeightSet || (min > aSize.height && canOverride)) { aSize.height = min; aHeightSet = PR_TRUE; } } else if (minHeight.GetUnit() == eStyleUnit_Percent) { NS_ASSERTION(position->mMinHeight.GetPercentValue() == 0.0f, "Non-zero percentage values not currently supported"); aSize.height = 0; aHeightSet = PR_TRUE; // FIXME: should we really do this for // nonzero values? } // calc() with percentage is treated like '0' (unset) nsIContent* content = aBox->GetContent(); if (content) { nsAutoString value; PRInt32 error; content->GetAttr(kNameSpaceID_None, nsGkAtoms::minwidth, value); if (!value.IsEmpty()) { value.Trim("%"); nscoord val = nsPresContext::CSSPixelsToAppUnits(value.ToInteger(&error)); if (val > aSize.width) aSize.width = val; aWidthSet = PR_TRUE; } content->GetAttr(kNameSpaceID_None, nsGkAtoms::minheight, value); if (!value.IsEmpty()) { value.Trim("%"); nscoord val = nsPresContext::CSSPixelsToAppUnits(value.ToInteger(&error)); if (val > aSize.height) aSize.height = val; aHeightSet = PR_TRUE; } } return (aWidthSet && aHeightSet); }
nscoord nsListBoxBodyFrame::ComputeIntrinsicISize(nsBoxLayoutState& aBoxLayoutState) { if (mStringWidth != -1) return mStringWidth; nscoord largestWidth = 0; int32_t index = 0; nsCOMPtr<nsIDOMElement> firstRowEl; GetItemAtIndex(index, getter_AddRefs(firstRowEl)); nsCOMPtr<nsIContent> firstRowContent(do_QueryInterface(firstRowEl)); if (firstRowContent) { RefPtr<nsStyleContext> styleContext; nsPresContext *presContext = aBoxLayoutState.PresContext(); styleContext = presContext->StyleSet()-> ResolveStyleFor(firstRowContent->AsElement(), nullptr, ConsumeStyleBehavior::DontConsume, LazyComputeBehavior::Allow); nscoord width = 0; nsMargin margin(0,0,0,0); if (styleContext->StylePadding()->GetPadding(margin)) width += margin.LeftRight(); width += styleContext->StyleBorder()->GetComputedBorder().LeftRight(); if (styleContext->StyleMargin()->GetMargin(margin)) width += margin.LeftRight(); FlattenedChildIterator iter(mContent); for (nsIContent* child = iter.GetNextChild(); child; child = iter.GetNextChild()) { if (child->IsXULElement(nsGkAtoms::listitem)) { nsRenderingContext* rendContext = aBoxLayoutState.GetRenderingContext(); if (rendContext) { nsAutoString value; uint32_t textCount = child->GetChildCount(); for (uint32_t j = 0; j < textCount; ++j) { nsIContent* text = child->GetChildAt(j); if (text && text->IsNodeOfType(nsINode::eTEXT)) { text->AppendTextTo(value); } } RefPtr<nsFontMetrics> fm = nsLayoutUtils::GetFontMetricsForStyleContext(styleContext); nscoord textWidth = nsLayoutUtils::AppUnitWidthOfStringBidi(value, this, *fm, *rendContext); textWidth += width; if (textWidth > largestWidth) largestWidth = textWidth; } } } } mStringWidth = largestWidth; return mStringWidth; }
PRBool nsIBox::AddCSSMinSize(nsBoxLayoutState& aState, nsIBox* aBox, nsSize& aSize) { PRBool widthSet = PR_FALSE; PRBool heightSet = PR_FALSE; PRBool canOverride = PR_TRUE; // See if a native theme wants to supply a minimum size. const nsStyleDisplay* display = aBox->GetStyleDisplay(); if (display->mAppearance) { nsITheme *theme = aState.PresContext()->GetTheme(); if (theme && theme->ThemeSupportsWidget(aState.PresContext(), aBox, display->mAppearance)) { nsIntSize size; nsIRenderingContext* rendContext = aState.GetRenderingContext(); if (rendContext) { theme->GetMinimumWidgetSize(rendContext, aBox, display->mAppearance, &size, &canOverride); if (size.width) { aSize.width = aState.PresContext()->DevPixelsToAppUnits(size.width); widthSet = PR_TRUE; } if (size.height) { aSize.height = aState.PresContext()->DevPixelsToAppUnits(size.height); heightSet = PR_TRUE; } } } } // add in the css min, max, pref const nsStylePosition* position = aBox->GetStylePosition(); // same for min size. Unfortunately min size is always set to 0. So for now // we will assume 0 means not set. if (position->mMinWidth.GetUnit() == eStyleUnit_Coord) { nscoord min = position->mMinWidth.GetCoordValue(); if (min && (!widthSet || (min > aSize.width && canOverride))) { aSize.width = min; widthSet = PR_TRUE; } } else if (position->mMinWidth.GetUnit() == eStyleUnit_Percent) { NS_ASSERTION(position->mMinWidth.GetPercentValue() == 0.0f, "Non-zero percentage values not currently supported"); aSize.width = 0; widthSet = PR_TRUE; } // XXX Handle eStyleUnit_Enumerated? // (Handling the eStyleUnit_Enumerated types requires // GetPrefSize/GetMinSize methods that don't consider // (min-/max-/)(width/height) properties. if (position->mMinHeight.GetUnit() == eStyleUnit_Coord) { nscoord min = position->mMinHeight.GetCoordValue(); if (min && (!heightSet || (min > aSize.height && canOverride))) { aSize.height = min; heightSet = PR_TRUE; } } else if (position->mMinHeight.GetUnit() == eStyleUnit_Percent) { NS_ASSERTION(position->mMinHeight.GetPercentValue() == 0.0f, "Non-zero percentage values not currently supported"); aSize.height = 0; heightSet = PR_TRUE; } nsIContent* content = aBox->GetContent(); if (content) { nsAutoString value; PRInt32 error; content->GetAttr(kNameSpaceID_None, nsGkAtoms::minwidth, value); if (!value.IsEmpty()) { value.Trim("%"); nscoord val = nsPresContext::CSSPixelsToAppUnits(value.ToInteger(&error)); if (val > aSize.width) aSize.width = val; widthSet = PR_TRUE; } content->GetAttr(kNameSpaceID_None, nsGkAtoms::minheight, value); if (!value.IsEmpty()) { value.Trim("%"); nscoord val = nsPresContext::CSSPixelsToAppUnits(value.ToInteger(&error)); if (val > aSize.height) aSize.height = val; heightSet = PR_TRUE; } } return (widthSet && heightSet); }
nscoord nsListBoxBodyFrame::ComputeIntrinsicWidth(nsBoxLayoutState& aBoxLayoutState) { if (mStringWidth != -1) return mStringWidth; nscoord largestWidth = 0; PRInt32 index = 0; nsCOMPtr<nsIDOMElement> firstRowEl; GetItemAtIndex(index, getter_AddRefs(firstRowEl)); nsCOMPtr<nsIContent> firstRowContent(do_QueryInterface(firstRowEl)); if (firstRowContent) { nsRefPtr<nsStyleContext> styleContext; nsPresContext *presContext = aBoxLayoutState.PresContext(); styleContext = presContext->StyleSet()-> ResolveStyleFor(firstRowContent->AsElement(), nsnull); nscoord width = 0; nsMargin margin(0,0,0,0); if (styleContext->GetStylePadding()->GetPadding(margin)) width += margin.LeftRight(); width += styleContext->GetStyleBorder()->GetActualBorder().LeftRight(); if (styleContext->GetStyleMargin()->GetMargin(margin)) width += margin.LeftRight(); ChildIterator iter, last; PRUint32 i = 0; for (ChildIterator::Init(mContent, &iter, &last); iter != last && i < 100; ++iter, ++i) { nsIContent *child = (*iter); if (child->Tag() == nsGkAtoms::listitem) { nsRenderingContext* rendContext = aBoxLayoutState.GetRenderingContext(); if (rendContext) { nsAutoString value; PRUint32 textCount = child->GetChildCount(); for (PRUint32 j = 0; j < textCount; ++j) { nsIContent* text = child->GetChildAt(j); if (text && text->IsNodeOfType(nsINode::eTEXT)) { text->AppendTextTo(value); } } nsRefPtr<nsFontMetrics> fm; nsLayoutUtils::GetFontMetricsForStyleContext(styleContext, getter_AddRefs(fm)); rendContext->SetFont(fm); nscoord textWidth = nsLayoutUtils::GetStringWidth(this, rendContext, value.get(), value.Length()); textWidth += width; if (textWidth > largestWidth) largestWidth = textWidth; } } } } mStringWidth = largestWidth; return mStringWidth; }
nscoord nsListBoxBodyFrame::ComputeIntrinsicWidth(nsBoxLayoutState& aBoxLayoutState) { if (mStringWidth != -1) return mStringWidth; nscoord largestWidth = 0; PRInt32 index = 0; nsCOMPtr<nsIDOMElement> firstRowEl; GetItemAtIndex(index, getter_AddRefs(firstRowEl)); nsCOMPtr<nsIContent> firstRowContent(do_QueryInterface(firstRowEl)); if (firstRowContent) { nsRefPtr<nsStyleContext> styleContext; nsPresContext *presContext = aBoxLayoutState.PresContext(); styleContext = presContext->StyleSet()-> ResolveStyleFor(firstRowContent, nsnull); nscoord width = 0; nsMargin margin(0,0,0,0); if (styleContext->GetStylePadding()->GetPadding(margin)) width += margin.LeftRight(); width += styleContext->GetStyleBorder()->GetBorder().LeftRight(); if (styleContext->GetStyleMargin()->GetMargin(margin)) width += margin.LeftRight(); nsIContent* listbox = mContent->GetBindingParent(); NS_ENSURE_TRUE(listbox, largestWidth); PRUint32 childCount = listbox->GetChildCount(); for (PRUint32 i = 0; i < childCount && i < 100; ++i) { nsIContent *child = listbox->GetChildAt(i); if (child->Tag() == nsGkAtoms::listitem) { nsIRenderingContext* rendContext = aBoxLayoutState.GetRenderingContext(); if (rendContext) { nsAutoString value; PRUint32 textCount = child->GetChildCount(); for (PRUint32 j = 0; j < textCount; ++j) { nsIContent* text = child->GetChildAt(j); if (text && text->IsNodeOfType(nsINode::eTEXT)) { text->AppendTextTo(value); } } nsLayoutUtils::SetFontFromStyle(rendContext, styleContext); nscoord textWidth = nsLayoutUtils::GetStringWidth(this, rendContext, value.get(), value.Length()); textWidth += width; if (textWidth > largestWidth) largestWidth = textWidth; } } } } mStringWidth = largestWidth; return mStringWidth; }