void nsTextBoxFrame::PaintTitle(nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect, nsPoint aPt) { if (mTitle.IsEmpty()) return; nsRect textRect(CalcTextRect(aRenderingContext, aPt)); // Paint the text shadow before doing any foreground stuff const nsStyleText* textStyle = GetStyleText(); if (textStyle->mTextShadow) { // Text shadow happens with the last value being painted at the back, // ie. it is painted first. for (PRUint32 i = textStyle->mTextShadow->Length(); i > 0; --i) { PaintOneShadow(aRenderingContext.ThebesContext(), textRect, textStyle->mTextShadow->ShadowAt(i - 1), GetStyleColor()->mColor, aDirtyRect); } } DrawText(aRenderingContext, textRect, nsnull); }
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; }
nsRect nsTextBoxFrame::CalcTextRect(nsIRenderingContext &aRenderingContext, const nsPoint &aTextOrigin) { nsRect textRect(aTextOrigin, GetSize()); nsMargin borderPadding; GetBorderAndPadding(borderPadding); textRect.Deflate(borderPadding); // determine (cropped) title and underline position nsPresContext* presContext = PresContext(); LayoutTitle(presContext, aRenderingContext, textRect); // make the rect as small as our (cropped) text. nscoord outerWidth = textRect.width; textRect.width = mTitleWidth; // Align our text within the overall rect by checking our text-align property. const nsStyleVisibility* vis = GetStyleVisibility(); const nsStyleText* textStyle = GetStyleText(); if (textStyle->mTextAlign == NS_STYLE_TEXT_ALIGN_CENTER) textRect.x += (outerWidth - textRect.width)/2; else if (textStyle->mTextAlign == NS_STYLE_TEXT_ALIGN_RIGHT || (textStyle->mTextAlign == NS_STYLE_TEXT_ALIGN_DEFAULT && vis->mDirection == NS_STYLE_DIRECTION_RTL) || (textStyle->mTextAlign == NS_STYLE_TEXT_ALIGN_END && vis->mDirection == NS_STYLE_DIRECTION_LTR)) { textRect.x += (outerWidth - textRect.width); } return textRect; }
nsresult nsGfxButtonControlFrame::GetLabel(nsXPIDLString& aLabel) { // Get the text from the "value" property on our content if there is // one; otherwise set it to a default value (localized). nsresult rv; nsCOMPtr<nsIDOMHTMLInputElement> elt = do_QueryInterface(mContent); if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::value) && elt) { rv = elt->GetValue(aLabel); } else { // Generate localized label. // We can't make any assumption as to what the default would be // because the value is localized for non-english platforms, thus // it might not be the string "Reset", "Submit Query", or "Browse..." rv = GetDefaultLabel(aLabel); } NS_ENSURE_SUCCESS(rv, rv); // Compress whitespace out of label if needed. if (!GetStyleText()->WhiteSpaceIsSignificant()) { aLabel.CompressWhitespace(); } else if (aLabel.Length() > 2 && aLabel.First() == ' ' && aLabel.CharAt(aLabel.Length() - 1) == ' ') { // This is a bit of a hack. The reason this is here is as follows: we now // have default padding on our buttons to make them non-ugly. // Unfortunately, IE-windows does not have such padding, so people will // stick values like " ok " (with the spaces) in the buttons in an attempt // to make them look decent. Unfortunately, if they do this the button // looks way too big in Mozilla. Worse yet, if they do this _and_ set a // fixed width for the button we run into trouble because our focus-rect // border/padding and outer border take up 10px of the horizontal button // space or so; the result is that the text is misaligned, even with the // recentering we do in nsHTMLButtonFrame::Reflow. So to solve this, even // if the whitespace is significant, single leading and trailing _spaces_ // (and not other whitespace) are removed. The proper solution, of // course, is to not have the focus rect painting taking up 6px of // horizontal space. We should do that instead (via XBL form controls or // changing the renderer) and remove this. aLabel.Cut(0, 1); aLabel.Truncate(aLabel.Length() - 1); } return NS_OK; }
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; }