void nsFieldSetFrame::PaintBorderBackground(nsRenderingContext& aRenderingContext, nsPoint aPt, const nsRect& aDirtyRect, uint32_t aBGFlags) { // if the border is smaller than the legend. Move the border down // to be centered on the legend. // FIXME: This means border-radius clamping is incorrect; we should // override nsIFrame::GetBorderRadii. nsRect rect = VisualBorderRectRelativeToSelf(); nscoord yoff = rect.y; rect += aPt; nsPresContext* presContext = PresContext(); nsCSSRendering::PaintBackground(presContext, aRenderingContext, this, aDirtyRect, rect, aBGFlags); nsCSSRendering::PaintBoxShadowInner(presContext, aRenderingContext, this, rect, aDirtyRect); if (nsIFrame* legend = GetLegend()) { nscoord topBorder = StyleBorder()->GetComputedBorderWidth(NS_SIDE_TOP); // Use the rect of the legend frame, not mLegendRect, so we draw our // border under the legend's left and right margins. nsRect legendRect = legend->GetRect() + aPt; // we should probably use PaintBorderEdges to do this but for now just use clipping // to achieve the same effect. // draw left side nsRect clipRect(rect); clipRect.width = legendRect.x - rect.x; clipRect.height = topBorder; aRenderingContext.PushState(); aRenderingContext.IntersectClip(clipRect); nsCSSRendering::PaintBorder(presContext, aRenderingContext, this, aDirtyRect, rect, mStyleContext); aRenderingContext.PopState(); // draw right side clipRect = rect; clipRect.x = legendRect.XMost(); clipRect.width = rect.XMost() - legendRect.XMost(); clipRect.height = topBorder; aRenderingContext.PushState(); aRenderingContext.IntersectClip(clipRect); nsCSSRendering::PaintBorder(presContext, aRenderingContext, this, aDirtyRect, rect, mStyleContext); aRenderingContext.PopState(); // draw bottom clipRect = rect; clipRect.y += topBorder; clipRect.height = mRect.height - (yoff + topBorder); aRenderingContext.PushState(); aRenderingContext.IntersectClip(clipRect); nsCSSRendering::PaintBorder(presContext, aRenderingContext, this, aDirtyRect, rect, mStyleContext); aRenderingContext.PopState(); } else { nsCSSRendering::PaintBorder(presContext, aRenderingContext, this, aDirtyRect, nsRect(aPt, mRect.Size()), mStyleContext); } }
// Draw a header or footer string // @param aRenderingContext - rendering context to draw into // @param aHeaderFooter - indicates whether it is a header or footer // @param aJust - indicates where the string is located within the header/footer // @param aStr - the string to be drawn // @param aRect - the rect of the page // @param aHeight - the height of the font // @param aAscent - the ascent of the font // @param aWidth - available width for the string void nsPageFrame::DrawHeaderFooter(nsRenderingContext& aRenderingContext, nsHeaderFooterEnum aHeaderFooter, int32_t aJust, const nsString& aStr, const nsRect& aRect, nscoord aAscent, nscoord aHeight, nscoord aWidth) { nscoord contentWidth = aWidth - (mPD->mEdgePaperMargin.left + mPD->mEdgePaperMargin.right); if ((aHeaderFooter == eHeader && aHeight < mPD->mReflowMargin.top) || (aHeaderFooter == eFooter && aHeight < mPD->mReflowMargin.bottom)) { nsAutoString str; ProcessSpecialCodes(aStr, str); int32_t indx; int32_t textWidth = 0; const PRUnichar* text = str.get(); int32_t len = (int32_t)str.Length(); if (len == 0) { return; // bail is empty string } // find how much text fits, the "position" is the size of the available area if (nsLayoutUtils::BinarySearchForPosition(&aRenderingContext, text, 0, 0, 0, len, int32_t(contentWidth), indx, textWidth)) { if (indx < len-1 ) { // we can't fit in all the text if (indx > 3) { // But we can fit in at least 4 chars. Show all but 3 of them, then // an ellipsis. // XXXbz for non-plane0 text, this may be cutting things in the // middle of a codepoint! Also, we have no guarantees that the three // dots will fit in the space the three chars we removed took up with // these font metrics! str.Truncate(indx-3); str.AppendLiteral("..."); } else { // We can only fit 3 or fewer chars. Just show nothing str.Truncate(); } } } else { return; // bail if couldn't find the correct length } if (HasRTLChars(str)) { PresContext()->SetBidiEnabled(); } // cacl the x and y positions of the text nscoord x = GetXPosition(aRenderingContext, aRect, aJust, str); nscoord y; if (aHeaderFooter == eHeader) { y = aRect.y + mPD->mExtraMargin.top + mPD->mEdgePaperMargin.top; } else { y = aRect.YMost() - aHeight - mPD->mExtraMargin.bottom - mPD->mEdgePaperMargin.bottom; } // set up new clip and draw the text aRenderingContext.PushState(); aRenderingContext.SetColor(NS_RGB(0,0,0)); aRenderingContext.IntersectClip(aRect); nsLayoutUtils::DrawString(this, &aRenderingContext, str.get(), str.Length(), nsPoint(x, y + aAscent)); aRenderingContext.PopState(); } }