/* static */ void nsMathMLFrame::GetAxisHeight(nsIRenderingContext& aRenderingContext, nsIFontMetrics* aFontMetrics, nscoord& aAxisHeight) { // get the bounding metrics of the minus sign, the rendering context // is assumed to have been set with the font of the current style context #ifdef NS_DEBUG nsCOMPtr<nsIFontMetrics> currFontMetrics; aRenderingContext.GetFontMetrics(*getter_AddRefs(currFontMetrics)); NS_ASSERTION(currFontMetrics->Font().Equals(aFontMetrics->Font()), "unexpected state"); #endif nscoord xHeight; aFontMetrics->GetXHeight(xHeight); PRUnichar minus = 0x2212; // not '-', but official Unicode minus sign nsBoundingMetrics bm; nsresult rv = aRenderingContext.GetBoundingMetrics(&minus, PRUint32(1), bm); if (NS_SUCCEEDED(rv)) { aAxisHeight = bm.ascent - (bm.ascent + bm.descent)/2; } if (NS_FAILED(rv) || aAxisHeight <= 0 || aAxisHeight >= xHeight) { // fall-back to the other version GetAxisHeight(aFontMetrics, aAxisHeight); } }
void nsPageFrame::PaintHeaderFooter(nsIRenderingContext& aRenderingContext, nsPoint aPt) { nsPresContext* pc = PresContext(); if (!mPD->mPrintSettings) { if (pc->Type() == nsPresContext::eContext_PrintPreview || pc->IsDynamic()) mPD->mPrintSettings = pc->GetPrintSettings(); if (!mPD->mPrintSettings) return; } nsRect rect(aPt.x, aPt.y, mRect.width - mPD->mShadowSize.width, mRect.height - mPD->mShadowSize.height); aRenderingContext.SetColor(NS_RGB(0,0,0)); // Get the FontMetrics to determine width.height of strings nsCOMPtr<nsIFontMetrics> fontMet; pc->DeviceContext()->GetMetricsFor(*mPD->mHeadFootFont, pc->GetUserFontSet(), *getter_AddRefs(fontMet)); aRenderingContext.SetFont(fontMet); nscoord ascent = 0; nscoord visibleHeight = 0; if (fontMet) { fontMet->GetHeight(visibleHeight); fontMet->GetMaxAscent(ascent); } // print document headers and footers nsXPIDLString headerLeft, headerCenter, headerRight; mPD->mPrintSettings->GetHeaderStrLeft(getter_Copies(headerLeft)); mPD->mPrintSettings->GetHeaderStrCenter(getter_Copies(headerCenter)); mPD->mPrintSettings->GetHeaderStrRight(getter_Copies(headerRight)); DrawHeaderFooter(aRenderingContext, eHeader, headerLeft, headerCenter, headerRight, rect, ascent, visibleHeight); nsXPIDLString footerLeft, footerCenter, footerRight; mPD->mPrintSettings->GetFooterStrLeft(getter_Copies(footerLeft)); mPD->mPrintSettings->GetFooterStrCenter(getter_Copies(footerCenter)); mPD->mPrintSettings->GetFooterStrRight(getter_Copies(footerRight)); DrawHeaderFooter(aRenderingContext, eFooter, footerLeft, footerCenter, footerRight, rect, ascent, visibleHeight); }
//------------------------------------------------------------------------------ void nsPageFrame::PaintPageContent(nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect, nsPoint aPt) { nsIFrame* pageContentFrame = mFrames.FirstChild(); nsRect rect = aDirtyRect; float scale = PresContext()->GetPageScale(); aRenderingContext.PushState(); nsPoint framePos = aPt + pageContentFrame->GetOffsetTo(this); aRenderingContext.Translate(framePos.x, framePos.y); // aPt translates to coords relative to this, then margins translate to // pageContentFrame's coords rect -= framePos; aRenderingContext.Scale(scale, scale); rect.ScaleRoundOut(1.0f / scale); // Make sure we don't draw where we aren't supposed to draw, especially // when printing selection nsRect clipRect(nsPoint(0, 0), pageContentFrame->GetSize()); // Note: this computation matches how we compute maxSize.height // in nsPageFrame::Reflow nscoord expectedPageContentHeight = NSToCoordCeil((GetSize().height - mPD->mReflowMargin.TopBottom()) / scale); if (clipRect.height > expectedPageContentHeight) { // We're doing print-selection, with one long page-content frame. // Clip to the appropriate page-content slice for the current page. NS_ASSERTION(mPageNum > 0, "page num should be positive"); // Note: The pageContentFrame's y-position has been set such that a zero // y-value matches the top edge of the current page. So, to clip to the // current page's content (in coordinates *relative* to the page content // frame), we just negate its y-position and add the top margin. clipRect.y = NSToCoordCeil((-pageContentFrame->GetRect().y + mPD->mReflowMargin.top) / scale); clipRect.height = expectedPageContentHeight; NS_ASSERTION(clipRect.y < pageContentFrame->GetSize().height, "Should be clipping to region inside the page content bounds"); } aRenderingContext.SetClipRect(clipRect, nsClipCombine_kIntersect); nsRect backgroundRect = nsRect(nsPoint(0, 0), pageContentFrame->GetSize()); nsCSSRendering::PaintBackground(PresContext(), aRenderingContext, this, rect, backgroundRect, nsCSSRendering::PAINTBG_SYNC_DECODE_IMAGES); nsLayoutUtils::PaintFrame(&aRenderingContext, pageContentFrame, nsRegion(rect), NS_RGBA(0,0,0,0), nsLayoutUtils::PAINT_SYNC_DECODE_IMAGES); aRenderingContext.PopState(); }
NS_IMETHODIMP nsScrollPortView::Paint(nsIRenderingContext& aRC, const nsIRegion& aRegion, PRUint32 aPaintFlags, PRBool &aResult) { aRC.PushState(); nsRect bounds; GetDimensions(bounds); bounds.x = bounds.y = 0; aRC.SetClipRect(bounds, nsClipCombine_kIntersect); nsresult rv = nsView::Paint(aRC, aRegion, aPaintFlags, aResult); aRC.PopState(); return rv; }
static void PaintCheckMark(nsIRenderingContext& aRenderingContext, const nsRect& aRect) { // Points come from the coordinates on a 7X7 unit box centered at 0,0 const PRInt32 checkPolygonX[] = { -3, -1, 3, 3, -1, -3 }; const PRInt32 checkPolygonY[] = { -1, 1, -3, -1, 3, 1 }; const PRInt32 checkNumPoints = sizeof(checkPolygonX) / sizeof(PRInt32); const PRInt32 checkSize = 9; // This is value is determined by adding 2 // units to pad the 7x7 unit checkmark // Scale the checkmark based on the smallest dimension nscoord paintScale = PR_MIN(aRect.width, aRect.height) / checkSize; nsPoint paintCenter(aRect.x + aRect.width / 2, aRect.y + aRect.height / 2); nsPoint paintPolygon[checkNumPoints]; // Convert checkmark for screen rendering for (PRInt32 polyIndex = 0; polyIndex < checkNumPoints; polyIndex++) { paintPolygon[polyIndex] = paintCenter + nsPoint(checkPolygonX[polyIndex] * paintScale, checkPolygonY[polyIndex] * paintScale); } aRenderingContext.FillPolygon(paintPolygon, checkNumPoints); }
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 nsMathMLmsqrtFrame::Paint(nsPresContext* aPresContext, nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer, PRUint32 aFlags) { ///////////// // paint the content we are square-rooting nsresult rv = nsMathMLContainerFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); ///////////// // paint the sqrt symbol if (!NS_MATHML_HAS_ERROR(mPresentationData.flags)) { mSqrChar.Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer, this); if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer && mStyleContext->GetStyleVisibility()->IsVisible() && !mBarRect.IsEmpty()) { // paint the overline bar const nsStyleColor* color = GetStyleColor(); aRenderingContext.SetColor(color->mColor); aRenderingContext.FillRect(mBarRect); } #if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX) // for visual debug if (NS_MATHML_PAINT_BOUNDING_METRICS(mPresentationData.flags)) { nsRect rect; mSqrChar.GetRect(rect); nsBoundingMetrics bm; mSqrChar.GetBoundingMetrics(bm); aRenderingContext.SetColor(NS_RGB(255,0,0)); nscoord x = rect.x + bm.leftBearing; nscoord y = rect.y; nscoord w = bm.rightBearing - bm.leftBearing; nscoord h = bm.ascent + bm.descent; aRenderingContext.DrawRect(x,y,w,h); } #endif } return rv; }
void RectArea::Draw(nsIFrame* aFrame, nsIRenderingContext& aRC) { if (mHasFocus) { if (mNumCoords >= 4) { nscoord x1 = nsPresContext::CSSPixelsToAppUnits(mCoords[0]); nscoord y1 = nsPresContext::CSSPixelsToAppUnits(mCoords[1]); nscoord x2 = nsPresContext::CSSPixelsToAppUnits(mCoords[2]); nscoord y2 = nsPresContext::CSSPixelsToAppUnits(mCoords[3]); NS_ASSERTION(x1 <= x2 && y1 <= y2, "Someone screwed up RectArea::ParseCoords"); aRC.DrawLine(x1, y1, x1, y2); aRC.DrawLine(x1, y2, x2, y2); aRC.DrawLine(x1, y1, x2, y1); aRC.DrawLine(x2, y1, x2, y2); } } }
void DefaultArea::Draw(nsIFrame* aFrame, nsIRenderingContext& aRC) { if (mHasFocus) { nsRect r = aFrame->GetRect(); r.MoveTo(0, 0); nscoord x1 = r.x; nscoord y1 = r.y; const nscoord kOnePixel = nsPresContext::CSSPixelsToAppUnits(1); nscoord x2 = r.XMost() - kOnePixel; nscoord y2 = r.YMost() - kOnePixel; // XXX aRC.DrawRect(r) result is ugly, that's why we use DrawLine. aRC.DrawLine(x1, y1, x1, y2); aRC.DrawLine(x1, y2, x2, y2); aRC.DrawLine(x1, y1, x2, y1); aRC.DrawLine(x2, y1, x2, y2); } }
//------------------------------------------------------------------------------ void nsPageFrame::PaintPageContent(nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect, nsPoint aPt) { nsIFrame* pageContentFrame = mFrames.FirstChild(); nsRect rect = aDirtyRect; float scale = PresContext()->GetPageScale(); aRenderingContext.PushState(); nsPoint framePos = aPt + pageContentFrame->GetOffsetTo(this); aRenderingContext.Translate(framePos.x, framePos.y); // aPt translates to coords relative to this, then margins translate to // pageContentFrame's coords rect -= framePos; aRenderingContext.Scale(scale, scale); rect.ScaleRoundOut(1.0f / scale); // Make sure we don't draw where we aren't supposed to draw, especially // when printing selection nsRect clipRect(nsPoint(0, 0), pageContentFrame->GetSize()); // Note: this computation matches how we compute maxSize.height // in nsPageFrame::Reflow nscoord expectedPageContentHeight = NSToCoordCeil((GetSize().height - mPD->mReflowMargin.TopBottom()) / scale); if (clipRect.height > expectedPageContentHeight) { // We're doing print-selection, with one long page-content frame. // Clip to the appropriate page-content slice for the current page. NS_ASSERTION(mPageNum > 0, "page num should be positive"); clipRect.y = expectedPageContentHeight * (mPageNum - 1); clipRect.height = expectedPageContentHeight; NS_ASSERTION(clipRect.y < pageContentFrame->GetSize().height, "Should be clipping to region inside the page content bounds"); } aRenderingContext.SetClipRect(clipRect, nsClipCombine_kIntersect); const nsStyleBorder* border = GetStyleBorder(); const nsStylePadding* padding = GetStylePadding(); nsRect backgroundRect = nsRect(nsPoint(0, 0), pageContentFrame->GetSize()); nsCSSRendering::PaintBackground(PresContext(), aRenderingContext, this, rect, backgroundRect, *border, *padding, PR_TRUE); nsLayoutUtils::PaintFrame(&aRenderingContext, pageContentFrame, nsRegion(rect), NS_RGBA(0,0,0,0)); aRenderingContext.PopState(); }
//------------------------------------------------------------------------------ void nsSimplePageSequenceFrame::PaintPageSequence(nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect, nsPoint aPt) { nsRect rect = aDirtyRect; float scale = PresContext()->GetPrintPreviewScale(); aRenderingContext.PushState(); nsPoint framePos = aPt; aRenderingContext.Translate(framePos.x, framePos.y); rect -= framePos; aRenderingContext.Scale(scale, scale); rect.ScaleRoundOut(1.0f / scale); // Now the rect and the rendering coordinates are are relative to this frame. // Loop over the pages and paint them. nsIFrame* child = GetFirstChild(nsnull); while (child) { nsPoint pt = child->GetPosition(); // The rendering context has to be translated before each call to PaintFrame aRenderingContext.PushState(); aRenderingContext.Translate(pt.x, pt.y); nsLayoutUtils::PaintFrame(&aRenderingContext, child, nsRegion(rect - pt), NS_RGBA(0,0,0,0)); aRenderingContext.PopState(); child = child->GetNextSibling(); } aRenderingContext.PopState(); }
void nsPageFrame::PaintPrintPreviewBackground(nsIRenderingContext& aRenderingContext, nsPoint aPt) { // fill page with White aRenderingContext.SetColor(NS_RGB(255,255,255)); // REVIEW: this used to have rect's width and height be the // mClipRect if specialClipIsSet ... but that seems completely bogus // and inconsistent with the painting of the shadow below nsRect rect(aPt, GetSize()); rect.width -= mPD->mShadowSize.width; rect.height -= mPD->mShadowSize.height; aRenderingContext.FillRect(rect); // draw line around outside of page aRenderingContext.SetColor(NS_RGB(0,0,0)); aRenderingContext.DrawRect(rect); if (mPD->mShadowSize.width > 0 && mPD->mShadowSize.height > 0) { aRenderingContext.SetColor(NS_RGB(51,51,51)); nsRect r(aPt.x,aPt.y, mRect.width, mRect.height); nsRect shadowRect; shadowRect.x = r.x + r.width - mPD->mShadowSize.width; shadowRect.y = r.y + mPD->mShadowSize.height; shadowRect.width = mPD->mShadowSize.width; shadowRect.height = r.height - mPD->mShadowSize.height; aRenderingContext.FillRect(shadowRect); shadowRect.x = r.x + mPD->mShadowSize.width; shadowRect.y = r.y + r.height - mPD->mShadowSize.height; shadowRect.width = r.width - mPD->mShadowSize.width; shadowRect.height = mPD->mShadowSize.height; aRenderingContext.FillRect(shadowRect); } }
void nsHTMLContainerFrame::PaintDecorationsAndChildren( nsPresContext* aPresContext, nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer, PRBool aIsBlock, PRUint32 aFlags) { // Do standards mode painting of 'text-decoration's: under+overline // behind children, line-through in front. For Quirks mode, see // nsTextFrame::PaintTextDecorations. (See bug 1777.) nscolor underColor, overColor, strikeColor; PRUint8 decorations = NS_STYLE_TEXT_DECORATION_NONE; nsCOMPtr<nsIFontMetrics> fm; PRBool isVisible; if (eCompatibility_NavQuirks != aPresContext->CompatibilityMode() && NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer && NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && isVisible) { GetTextDecorations(aPresContext, aIsBlock, decorations, underColor, overColor, strikeColor); if (decorations & (NS_STYLE_TEXT_DECORATION_UNDERLINE | NS_STYLE_TEXT_DECORATION_OVERLINE | NS_STYLE_TEXT_DECORATION_LINE_THROUGH)) { const nsStyleFont* font = GetStyleFont(); NS_ASSERTION(font->mFont.decorations == NS_FONT_DECORATION_NONE, "fonts on style structs shouldn't have decorations"); // XXX This is relatively slow and shouldn't need to be used here. nsCOMPtr<nsIDeviceContext> deviceContext; aRenderingContext.GetDeviceContext(*getter_AddRefs(deviceContext)); nsCOMPtr<nsIFontMetrics> normalFont; const nsStyleVisibility* visibility = GetStyleVisibility(); deviceContext->GetMetricsFor(font->mFont, visibility->mLangGroup, *getter_AddRefs(fm)); } if (decorations & NS_STYLE_TEXT_DECORATION_UNDERLINE) { PaintTextDecorations(aRenderingContext, fm, NS_STYLE_TEXT_DECORATION_UNDERLINE, underColor); } if (decorations & NS_STYLE_TEXT_DECORATION_OVERLINE) { PaintTextDecorations(aRenderingContext, fm, NS_STYLE_TEXT_DECORATION_OVERLINE, overColor); } } PaintChildren(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer, aFlags); if (decorations & NS_STYLE_TEXT_DECORATION_LINE_THROUGH) { PaintTextDecorations(aRenderingContext, fm, NS_STYLE_TEXT_DECORATION_LINE_THROUGH, strikeColor); } }
void nsTextBoxFrame::CalculateUnderline(nsIRenderingContext& aRenderingContext) { if (mAccessKeyInfo && mAccessKeyInfo->mAccesskeyIndex != kNotFound) { // Calculate all fields of mAccessKeyInfo which // are the same for both BiDi and non-BiDi frames. const PRUnichar *titleString = mCroppedTitle.get(); aRenderingContext.SetTextRunRTL(PR_FALSE); aRenderingContext.GetWidth(titleString[mAccessKeyInfo->mAccesskeyIndex], mAccessKeyInfo->mAccessWidth); nscoord offset, baseline; nsIFontMetrics *metrics; aRenderingContext.GetFontMetrics(metrics); metrics->GetUnderline(offset, mAccessKeyInfo->mAccessUnderlineSize); metrics->GetMaxAscent(baseline); NS_RELEASE(metrics); mAccessKeyInfo->mAccessOffset = baseline - offset; } }
void PolyArea::Draw(nsIFrame* aFrame, nsIRenderingContext& aRC) { if (mHasFocus) { if (mNumCoords >= 6) { nscoord x0 = nsPresContext::CSSPixelsToAppUnits(mCoords[0]); nscoord y0 = nsPresContext::CSSPixelsToAppUnits(mCoords[1]); nscoord x1, y1; for (PRInt32 i = 2; i < mNumCoords; i += 2) { x1 = nsPresContext::CSSPixelsToAppUnits(mCoords[i]); y1 = nsPresContext::CSSPixelsToAppUnits(mCoords[i+1]); aRC.DrawLine(x0, y0, x1, y1); x0 = x1; y0 = y1; } x1 = nsPresContext::CSSPixelsToAppUnits(mCoords[0]); y1 = nsPresContext::CSSPixelsToAppUnits(mCoords[1]); aRC.DrawLine(x0, y0, x1, y1); } } }
/*virtual*/ void nsHTMLContainerFrame::PaintTextDecorationLines( nsIRenderingContext& aRenderingContext, nscolor aColor, nscoord aOffset, nscoord aAscent, nscoord aSize) { nsMargin bp; CalcBorderPadding(bp); PRIntn skip = GetSkipSides(); NS_FOR_CSS_SIDES(side) { if (skip & (1 << side)) { bp.side(side) = 0; } } aRenderingContext.SetColor(aColor); nscoord innerWidth = mRect.width - bp.left - bp.right; aRenderingContext.FillRect(bp.left, bp.top + aAscent - aOffset, innerWidth, aSize); }
NS_IMETHODIMP nsPlaceholderFrame::Paint(nsPresContext* aPresContext, nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer, PRUint32 aFlags) { if ((NS_FRAME_PAINT_LAYER_DEBUG == aWhichLayer) && GetShowFrameBorders()) { float p2t; p2t = aPresContext->PixelsToTwips(); aRenderingContext.SetColor(NS_RGB(0, 255, 255)); nscoord x = NSIntPixelsToTwips(-5, p2t); aRenderingContext.FillRect(x, 0, NSIntPixelsToTwips(13, p2t), NSIntPixelsToTwips(3, p2t)); nscoord y = NSIntPixelsToTwips(-10, p2t); aRenderingContext.FillRect(0, y, NSIntPixelsToTwips(3, p2t), NSIntPixelsToTwips(10, p2t)); } DO_GLOBAL_REFLOW_COUNT_DSP("nsPlaceholderFrame", &aRenderingContext); return NS_OK; }
void nsTextBoxFrame::GetTextSize(nsPresContext* aPresContext, nsIRenderingContext& aRenderingContext, const nsString& aString, nsSize& aSize, nscoord& aAscent) { nsCOMPtr<nsIFontMetrics> fontMet; nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fontMet)); fontMet->GetHeight(aSize.height); aRenderingContext.SetFont(fontMet); aSize.width = nsLayoutUtils::GetStringWidth(this, &aRenderingContext, aString.get(), aString.Length()); fontMet->GetMaxAscent(aAscent); }
void nsComboboxControlFrame::PaintFocus(nsIRenderingContext& aRenderingContext, nsPoint aPt) { /* Do we need to do anything? */ if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::disabled) || mFocused != this) return; aRenderingContext.PushState(); nsRect clipRect = mDisplayFrame->GetRect() + aPt; aRenderingContext.SetClipRect(clipRect, nsClipCombine_kIntersect); // REVIEW: Why does the old code paint mDisplayFrame again? We've // already painted it in the children above. So clipping it here won't do // us much good. ///////////////////// // draw focus aRenderingContext.SetLineStyle(nsLineStyle_kDotted); aRenderingContext.SetColor(GetStyleColor()->mColor); //aRenderingContext.DrawRect(clipRect); nscoord onePixel = nsPresContext::CSSPixelsToAppUnits(1); clipRect.width -= onePixel; clipRect.height -= onePixel; aRenderingContext.DrawLine(clipRect.x, clipRect.y, clipRect.x+clipRect.width, clipRect.y); aRenderingContext.DrawLine(clipRect.x+clipRect.width, clipRect.y, clipRect.x+clipRect.width, clipRect.y+clipRect.height); aRenderingContext.DrawLine(clipRect.x+clipRect.width, clipRect.y+clipRect.height, clipRect.x, clipRect.y+clipRect.height); aRenderingContext.DrawLine(clipRect.x, clipRect.y+clipRect.height, clipRect.x, clipRect.y); aRenderingContext.DrawLine(clipRect.x, clipRect.y+clipRect.height, clipRect.x, clipRect.y); aRenderingContext.PopState(); }
nsresult nsTableCellFrame::DecorateForSelection(nsPresContext* aPresContext, nsIRenderingContext& aRenderingContext, const nsStyleBackground *aStyleColor) { PRInt16 displaySelection; displaySelection = DisplaySelection(aPresContext); if (displaySelection) { PRBool isSelected = (GetStateBits() & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT; if (isSelected) { nsIFrameSelection *frameSelection = aPresContext->PresShell()->FrameSelection(); PRBool tableCellSelectionMode; nsresult result = frameSelection->GetTableCellSelection(&tableCellSelectionMode); if (NS_SUCCEEDED(result) && tableCellSelectionMode) { nscolor bordercolor; if (displaySelection == nsISelectionController::SELECTION_DISABLED) { bordercolor = NS_RGB(176,176,176);// disabled color } else { aPresContext->LookAndFeel()-> GetColor(nsILookAndFeel::eColor_TextSelectBackground, bordercolor); } PRInt16 t2p = (PRInt16) aPresContext->PixelsToTwips(); if ((mRect.width >(3*t2p)) && (mRect.height > (3*t2p))) { //compare bordercolor to ((nsStyleColor *)myColor)->mBackgroundColor) bordercolor = EnsureDifferentColors(bordercolor, aStyleColor->mBackgroundColor); //outerrounded aRenderingContext.SetColor(bordercolor); aRenderingContext.DrawLine(t2p, 0, mRect.width, 0); aRenderingContext.DrawLine(0, t2p, 0, mRect.height); aRenderingContext.DrawLine(t2p, mRect.height, mRect.width, mRect.height); aRenderingContext.DrawLine(mRect.width, t2p, mRect.width, mRect.height); //middle aRenderingContext.DrawRect(t2p, t2p, mRect.width-t2p, mRect.height-t2p); //shading aRenderingContext.DrawLine(2*t2p, mRect.height-2*t2p, mRect.width-t2p, mRect.height- (2*t2p)); aRenderingContext.DrawLine(mRect.width - (2*t2p), 2*t2p, mRect.width - (2*t2p), mRect.height-t2p); } } } } return NS_OK; }
/* static */ void nsMathMLFrame::GetRuleThickness(nsIRenderingContext& aRenderingContext, nsIFontMetrics* aFontMetrics, nscoord& aRuleThickness) { // get the bounding metrics of the overbar char, the rendering context // is assumed to have been set with the font of the current style context #ifdef NS_DEBUG nsCOMPtr<nsIFontMetrics> currFontMetrics; aRenderingContext.GetFontMetrics(*getter_AddRefs(currFontMetrics)); NS_ASSERTION(currFontMetrics->Font().Equals(aFontMetrics->Font()), "unexpected state"); #endif nscoord xHeight; aFontMetrics->GetXHeight(xHeight); PRUnichar overBar = 0x00AF; nsBoundingMetrics bm; nsresult rv = aRenderingContext.GetBoundingMetrics(&overBar, PRUint32(1), bm); if (NS_SUCCEEDED(rv)) { aRuleThickness = bm.ascent + bm.descent; } if (NS_FAILED(rv) || aRuleThickness <= 0 || aRuleThickness >= xHeight) { // fall-back to the other version GetRuleThickness(aFontMetrics, aRuleThickness); } #if 0 nscoord oldRuleThickness; GetRuleThickness(aFontMetrics, oldRuleThickness); PRUnichar sqrt = 0xE063; // a sqrt glyph from TeX's CMEX font rv = aRenderingContext.GetBoundingMetrics(&sqrt, PRUint32(1), bm); nscoord sqrtrule = bm.ascent; // according to TeX, the ascent should be the rule printf("xheight:%4d rule:%4d oldrule:%4d sqrtrule:%4d\n", xHeight, aRuleThickness, oldRuleThickness, sqrtrule); #endif }
//------------------------------------------------------------ void nsGfxCheckboxControlFrame::PaintCheckBox(nsIRenderingContext& aRenderingContext, nsPoint aPt, const nsRect& aDirtyRect) { // REVIEW: moved the mAppearance test out so we avoid constructing // a display item if it's not needed nsRect checkRect(aPt, mRect.Size()); checkRect.Deflate(GetUsedBorderAndPadding()); const nsStyleColor* color = GetStyleColor(); aRenderingContext.SetColor(color->mColor); PaintCheckMark(aRenderingContext, checkRect); }
void CircleArea::Draw(nsIFrame* aFrame, nsIRenderingContext& aRC) { if (mHasFocus) { if (mNumCoords >= 3) { nscoord x1 = nsPresContext::CSSPixelsToAppUnits(mCoords[0]); nscoord y1 = nsPresContext::CSSPixelsToAppUnits(mCoords[1]); nscoord radius = nsPresContext::CSSPixelsToAppUnits(mCoords[2]); if (radius < 0) { return; } nscoord x = x1 - radius; nscoord y = y1 - radius; nscoord w = 2 * radius; aRC.DrawEllipse(x, y, w, w); } } }
void nsVideoFrame::PaintVideo(nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect, nsPoint aPt) { nsRect area = GetContentRect() - GetPosition() + aPt; nsHTMLVideoElement* element = static_cast<nsHTMLVideoElement*>(GetContent()); nsIntSize videoSize = element->GetVideoSize(nsIntSize(0, 0)); if (videoSize.width <= 0 || videoSize.height <= 0 || area.IsEmpty()) return; gfxContext* ctx = static_cast<gfxContext*>(aRenderingContext.GetNativeGraphicData(nsIRenderingContext::NATIVE_THEBES_CONTEXT)); nsPresContext* presContext = PresContext(); gfxRect r = gfxRect(presContext->AppUnitsToGfxUnits(area.x), presContext->AppUnitsToGfxUnits(area.y), presContext->AppUnitsToGfxUnits(area.width), presContext->AppUnitsToGfxUnits(area.height)); r = CorrectForAspectRatio(r, videoSize); element->Paint(ctx, nsLayoutUtils::GetGraphicsFilterForFrame(this), r); }
nsresult nsMathMLmfracFrame::PlaceInternal(nsIRenderingContext& aRenderingContext, PRBool aPlaceOrigin, nsHTMLReflowMetrics& aDesiredSize, PRBool aWidthOnly) { //////////////////////////////////// // Get the children's desired sizes nsBoundingMetrics bmNum, bmDen; nsHTMLReflowMetrics sizeNum; nsHTMLReflowMetrics sizeDen; nsIFrame* frameDen = nsnull; nsIFrame* frameNum = mFrames.FirstChild(); if (frameNum) frameDen = frameNum->GetNextSibling(); if (!frameNum || !frameDen || frameDen->GetNextSibling()) { // report an error, encourage people to get their markups in order return ReflowError(aRenderingContext, aDesiredSize); } GetReflowAndBoundingMetricsFor(frameNum, sizeNum, bmNum); GetReflowAndBoundingMetricsFor(frameDen, sizeDen, bmDen); nsPresContext* presContext = PresContext(); nscoord onePixel = nsPresContext::CSSPixelsToAppUnits(1); aRenderingContext.SetFont(GetStyleFont()->mFont, presContext->GetUserFontSet()); nsCOMPtr<nsIFontMetrics> fm; aRenderingContext.GetFontMetrics(*getter_AddRefs(fm)); nscoord defaultRuleThickness, axisHeight; GetRuleThickness(aRenderingContext, fm, defaultRuleThickness); GetAxisHeight(aRenderingContext, fm, axisHeight); nsEmbellishData coreData; GetEmbellishDataFrom(mEmbellishData.coreFrame, coreData); // see if the linethickness attribute is there nsAutoString value; GetAttribute(mContent, mPresentationData.mstyle, nsGkAtoms::linethickness_, value); mLineThickness = CalcLineThickness(presContext, mStyleContext, value, onePixel, defaultRuleThickness); if (!mIsBevelled) { mLineRect.height = mLineThickness; // by default, leave at least one-pixel padding at either end, or use // lspace & rspace that may come from <mo> if we are an embellished // container (we fetch values from the core since they may use units that // depend on style data, and style changes could have occurred in the // core since our last visit there) nscoord leftSpace = NS_MAX(onePixel, coreData.leftSpace); nscoord rightSpace = NS_MAX(onePixel, coreData.rightSpace); ////////////////// // Get shifts nscoord numShift = 0; nscoord denShift = 0; // Rule 15b, App. G, TeXbook nscoord numShift1, numShift2, numShift3; nscoord denShift1, denShift2; GetNumeratorShifts(fm, numShift1, numShift2, numShift3); GetDenominatorShifts(fm, denShift1, denShift2); if (NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)) { // C > T numShift = numShift1; denShift = denShift1; } else { numShift = (0 < mLineRect.height) ? numShift2 : numShift3; denShift = denShift2; } nscoord minClearance = 0; nscoord actualClearance = 0; nscoord actualRuleThickness = mLineThickness; if (0 == actualRuleThickness) { // Rule 15c, App. G, TeXbook // min clearance between numerator and denominator minClearance = (NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)) ? 7 * defaultRuleThickness : 3 * defaultRuleThickness; actualClearance = (numShift - bmNum.descent) - (bmDen.ascent - denShift); // actualClearance should be >= minClearance if (actualClearance < minClearance) { nscoord halfGap = (minClearance - actualClearance)/2; numShift += halfGap; denShift += halfGap; } } else { // Rule 15d, App. G, TeXbook // min clearance between numerator or denominator and middle of bar // TeX has a different interpretation of the thickness. // Try $a \above10pt b$ to see. Here is what TeX does: // minClearance = (NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)) ? // 3 * actualRuleThickness : actualRuleThickness; // we slightly depart from TeX here. We use the defaultRuleThickness instead // of the value coming from the linethickness attribute, i.e., we recover what // TeX does if the user hasn't set linethickness. But when the linethickness // is set, we avoid the wide gap problem. minClearance = (NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)) ? 3 * defaultRuleThickness : defaultRuleThickness + onePixel; // adjust numShift to maintain minClearance if needed actualClearance = (numShift - bmNum.descent) - (axisHeight + actualRuleThickness/2); if (actualClearance < minClearance) { numShift += (minClearance - actualClearance); } // adjust denShift to maintain minClearance if needed actualClearance = (axisHeight - actualRuleThickness/2) - (bmDen.ascent - denShift); if (actualClearance < minClearance) { denShift += (minClearance - actualClearance); } } ////////////////// // Place Children // XXX Need revisiting the width. TeX uses the exact width // e.g. in $$\huge\frac{\displaystyle\int}{i}$$ nscoord width = NS_MAX(bmNum.width, bmDen.width); nscoord dxNum = leftSpace + (width - sizeNum.width)/2; nscoord dxDen = leftSpace + (width - sizeDen.width)/2; width += leftSpace + rightSpace; // see if the numalign attribute is there GetAttribute(mContent, mPresentationData.mstyle, nsGkAtoms::numalign_, value); if (value.EqualsLiteral("left")) dxNum = leftSpace; else if (value.EqualsLiteral("right")) dxNum = width - rightSpace - sizeNum.width; // see if the denomalign attribute is there GetAttribute(mContent, mPresentationData.mstyle, nsGkAtoms::denomalign_, value); if (value.EqualsLiteral("left")) dxDen = leftSpace; else if (value.EqualsLiteral("right")) dxDen = width - rightSpace - sizeDen.width; mBoundingMetrics.rightBearing = NS_MAX(dxNum + bmNum.rightBearing, dxDen + bmDen.rightBearing); if (mBoundingMetrics.rightBearing < width - rightSpace) mBoundingMetrics.rightBearing = width - rightSpace; mBoundingMetrics.leftBearing = NS_MIN(dxNum + bmNum.leftBearing, dxDen + bmDen.leftBearing); if (mBoundingMetrics.leftBearing > leftSpace) mBoundingMetrics.leftBearing = leftSpace; mBoundingMetrics.ascent = bmNum.ascent + numShift; mBoundingMetrics.descent = bmDen.descent + denShift; mBoundingMetrics.width = width; aDesiredSize.ascent = sizeNum.ascent + numShift; aDesiredSize.height = aDesiredSize.ascent + sizeDen.height - sizeDen.ascent + denShift; aDesiredSize.width = mBoundingMetrics.width; aDesiredSize.mBoundingMetrics = mBoundingMetrics; mReference.x = 0; mReference.y = aDesiredSize.ascent; if (aPlaceOrigin) { nscoord dy; // place numerator dy = 0; FinishReflowChild(frameNum, presContext, nsnull, sizeNum, dxNum, dy, 0); // place denominator dy = aDesiredSize.height - sizeDen.height; FinishReflowChild(frameDen, presContext, nsnull, sizeDen, dxDen, dy, 0); // place the fraction bar - dy is top of bar dy = aDesiredSize.ascent - (axisHeight + actualRuleThickness/2); mLineRect.SetRect(leftSpace, dy, width - (leftSpace + rightSpace), actualRuleThickness); } } else { nscoord numShift = 0.0; nscoord denShift = 0.0; nscoord padding = 3 * defaultRuleThickness; nscoord slashRatio = 3; // Define the constant used in the expression of the maximum width nscoord em; fm->GetEmHeight(em); nscoord slashMaxWidthConstant = 2 * em; // For large line thicknesses the minimum slash height is limited to the // largest expected height of a fraction nscoord slashMinHeight = slashRatio * NS_MIN(2 * mLineThickness, slashMaxWidthConstant); nscoord leftSpace = NS_MAX(padding, coreData.leftSpace); nscoord rightSpace = NS_MAX(padding, coreData.rightSpace); nscoord delta; // ___________ // | | / // {|-NUMERATOR-| / // {|___________| S // { L // numShift{ A // ------------------------------------------------------- baseline // S _____________ } denShift // H | |} // / |-DENOMINATOR-|} // / |_____________| // // first, ensure that the top of the numerator is at least as high as the // top of the denominator (and the reverse for the bottoms) delta = NS_MAX(bmDen.ascent - bmNum.ascent, bmNum.descent - bmDen.descent) / 2; if (delta > 0) { numShift += delta; denShift += delta; } if (NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)) { delta = NS_MIN(bmDen.ascent + bmDen.descent, bmNum.ascent + bmNum.descent) / 2; numShift += delta; denShift += delta; } else { nscoord xHeight = 0; fm->GetXHeight (xHeight); numShift += xHeight / 2; denShift += xHeight / 4; } // Set the ascent/descent of our BoundingMetrics. mBoundingMetrics.ascent = bmNum.ascent + numShift; mBoundingMetrics.descent = bmDen.descent + denShift; // At this point the height of the slash is // mBoundingMetrics.ascent + mBoundingMetrics.descent // Ensure that it is greater than slashMinHeight delta = (slashMinHeight - (mBoundingMetrics.ascent + mBoundingMetrics.descent)) / 2; if (delta > 0) { mBoundingMetrics.ascent += delta; mBoundingMetrics.descent += delta; } // Set the width of the slash if (aWidthOnly) { mLineRect.width = mLineThickness + slashMaxWidthConstant; } else { mLineRect.width = mLineThickness + NS_MIN(slashMaxWidthConstant, (mBoundingMetrics.ascent + mBoundingMetrics.descent) / slashRatio); } // Set horizontal bounding metrics mBoundingMetrics.leftBearing = leftSpace + bmNum.leftBearing; mBoundingMetrics.rightBearing = leftSpace + bmNum.width + mLineRect.width + bmDen.rightBearing; mBoundingMetrics.width = leftSpace + bmNum.width + mLineRect.width + bmDen.width + rightSpace; // Set aDesiredSize aDesiredSize.ascent = mBoundingMetrics.ascent + padding; aDesiredSize.height = mBoundingMetrics.ascent + mBoundingMetrics.descent + 2 * padding; aDesiredSize.width = mBoundingMetrics.width; aDesiredSize.mBoundingMetrics = mBoundingMetrics; mReference.x = 0; mReference.y = aDesiredSize.ascent; if (aPlaceOrigin) { FinishReflowChild(frameNum, presContext, nsnull, sizeNum, leftSpace, aDesiredSize.ascent - numShift - sizeNum.ascent, 0); mLineRect.SetRect(leftSpace + bmNum.width, aDesiredSize.ascent - mBoundingMetrics.ascent, mLineRect.width, aDesiredSize.height - 2 * padding); FinishReflowChild(frameDen, presContext, nsnull, sizeDen, leftSpace + bmNum.width + mLineRect.width, aDesiredSize.ascent + denShift - sizeDen.ascent, 0); } } return NS_OK; }
NS_IMETHODIMP nsMathMLmunderoverFrame::Place(nsIRenderingContext& aRenderingContext, PRBool aPlaceOrigin, nsHTMLReflowMetrics& aDesiredSize) { if ( NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(mEmbellishData.flags) && !NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)) { // place like sub-superscript pair return nsMathMLmsubsupFrame::PlaceSubSupScript(GetPresContext(), aRenderingContext, aPlaceOrigin, aDesiredSize, this); } //////////////////////////////////// // Get the children's desired sizes nsBoundingMetrics bmBase, bmUnder, bmOver; nsHTMLReflowMetrics baseSize (nsnull); nsHTMLReflowMetrics underSize (nsnull); nsHTMLReflowMetrics overSize (nsnull); nsIFrame* overFrame = nsnull; nsIFrame* underFrame = nsnull; nsIFrame* baseFrame = mFrames.FirstChild(); if (baseFrame) underFrame = baseFrame->GetNextSibling(); if (underFrame) overFrame = underFrame->GetNextSibling(); if (!baseFrame || !underFrame || !overFrame || overFrame->GetNextSibling()) { // report an error, encourage people to get their markups in order NS_WARNING("invalid markup"); return ReflowError(aRenderingContext, aDesiredSize); } GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase); GetReflowAndBoundingMetricsFor(underFrame, underSize, bmUnder); GetReflowAndBoundingMetricsFor(overFrame, overSize, bmOver); nscoord onePixel = GetPresContext()->IntScaledPixelsToTwips(1); //////////////////// // Place Children aRenderingContext.SetFont(GetStyleFont()->mFont, nsnull); nsCOMPtr<nsIFontMetrics> fm; aRenderingContext.GetFontMetrics(*getter_AddRefs(fm)); nscoord xHeight = 0; fm->GetXHeight (xHeight); nscoord ruleThickness; GetRuleThickness (aRenderingContext, fm, ruleThickness); nscoord correction = 0; GetItalicCorrection (bmBase, correction); // there are 2 different types of placement depending on // whether we want an accented under or not nscoord underDelta1 = 0; // gap between base and underscript nscoord underDelta2 = 0; // extra space beneath underscript if (!NS_MATHML_EMBELLISH_IS_ACCENTUNDER(mEmbellishData.flags)) { // Rule 13a, App. G, TeXbook nscoord bigOpSpacing2, bigOpSpacing4, bigOpSpacing5, dummy; GetBigOpSpacings (fm, dummy, bigOpSpacing2, dummy, bigOpSpacing4, bigOpSpacing5); underDelta1 = PR_MAX(bigOpSpacing2, (bigOpSpacing4 - bmUnder.ascent)); underDelta2 = bigOpSpacing5; } else { // No corresponding rule in TeXbook - we are on our own here // XXX tune the gap delta between base and underscript // Should we use Rule 10 like \underline does? underDelta1 = ruleThickness + onePixel/2; underDelta2 = ruleThickness; } // empty under? if (!(bmUnder.ascent + bmUnder.descent)) underDelta1 = 0; nscoord overDelta1 = 0; // gap between base and overscript nscoord overDelta2 = 0; // extra space above overscript if (!NS_MATHML_EMBELLISH_IS_ACCENTOVER(mEmbellishData.flags)) { // Rule 13a, App. G, TeXbook nscoord bigOpSpacing1, bigOpSpacing3, bigOpSpacing5, dummy; GetBigOpSpacings (fm, bigOpSpacing1, dummy, bigOpSpacing3, dummy, bigOpSpacing5); overDelta1 = PR_MAX(bigOpSpacing1, (bigOpSpacing3 - bmOver.descent)); overDelta2 = bigOpSpacing5; // XXX This is not a TeX rule... // delta1 (as computed abvove) can become really big when bmOver.descent is // negative, e.g., if the content is &OverBar. In such case, we use the height if (bmOver.descent < 0) overDelta1 = PR_MAX(bigOpSpacing1, (bigOpSpacing3 - (bmOver.ascent + bmOver.descent))); } else { // Rule 12, App. G, TeXbook overDelta1 = ruleThickness + onePixel/2; if (bmBase.ascent < xHeight) { overDelta1 += xHeight - bmBase.ascent; } overDelta2 = ruleThickness; } // empty over? if (!(bmOver.ascent + bmOver.descent)) overDelta1 = 0; nscoord dxBase, dxOver = 0, dxUnder = 0; ////////// // pass 1, do what <mover> does: attach the overscript on the base // Ad-hoc - This is to override fonts which have ready-made _accent_ // glyphs with negative lbearing and rbearing. We want to position // the overscript ourselves nscoord overWidth = bmOver.width; if (!overWidth && (bmOver.rightBearing - bmOver.leftBearing > 0)) { overWidth = bmOver.rightBearing - bmOver.leftBearing; dxOver = -bmOver.leftBearing; } if (NS_MATHML_EMBELLISH_IS_ACCENTOVER(mEmbellishData.flags)) { mBoundingMetrics.width = bmBase.width; dxOver += correction + (mBoundingMetrics.width - overWidth)/2; } else { mBoundingMetrics.width = PR_MAX(bmBase.width, overWidth); dxOver += correction/2 + (mBoundingMetrics.width - overWidth)/2; } dxBase = (mBoundingMetrics.width - bmBase.width)/2; mBoundingMetrics.ascent = bmBase.ascent + overDelta1 + bmOver.ascent + bmOver.descent; mBoundingMetrics.descent = bmBase.descent + underDelta1 + bmUnder.ascent + bmUnder.descent; mBoundingMetrics.leftBearing = PR_MIN(dxBase + bmBase.leftBearing, dxOver + bmOver.leftBearing); mBoundingMetrics.rightBearing = PR_MAX(dxBase + bmBase.rightBearing, dxOver + bmOver.rightBearing); ////////// // pass 2, do what <munder> does: attach the underscript on the previous // result. We conceptually view the previous result as an "anynomous base" // from where to attach the underscript. Hence if the underscript is empty, // we should end up like <mover>. If the overscript is empty, we should // end up like <munder>. nsBoundingMetrics bmAnonymousBase = mBoundingMetrics; nscoord ascentAnonymousBase = PR_MAX(mBoundingMetrics.ascent + overDelta2, overSize.ascent + bmOver.descent + overDelta1 + bmBase.ascent); GetItalicCorrection(bmAnonymousBase, correction); nscoord maxWidth = PR_MAX(bmAnonymousBase.width, bmUnder.width); if (NS_MATHML_EMBELLISH_IS_ACCENTUNDER(mEmbellishData.flags)) { dxUnder = (maxWidth - bmUnder.width)/2;; } else { dxUnder = -correction/2 + (maxWidth - bmUnder.width)/2; } nscoord dxAnonymousBase = (maxWidth - bmAnonymousBase.width)/2; // adjust the offsets of the real base and overscript since their // final offsets should be relative to us... dxOver += dxAnonymousBase; dxBase += dxAnonymousBase; mBoundingMetrics.width = PR_MAX(dxAnonymousBase + bmAnonymousBase.width, dxUnder + bmUnder.width); mBoundingMetrics.leftBearing = PR_MIN(dxAnonymousBase + bmAnonymousBase.leftBearing, dxUnder + bmUnder.leftBearing); mBoundingMetrics.rightBearing = PR_MAX(dxAnonymousBase + bmAnonymousBase.rightBearing, dxUnder + bmUnder.rightBearing); aDesiredSize.ascent = ascentAnonymousBase; aDesiredSize.descent = PR_MAX(mBoundingMetrics.descent + underDelta2, bmAnonymousBase.descent + underDelta1 + bmUnder.ascent + underSize.descent); aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent; aDesiredSize.width = mBoundingMetrics.width; aDesiredSize.mBoundingMetrics = mBoundingMetrics; mReference.x = 0; mReference.y = aDesiredSize.ascent; if (aPlaceOrigin) { nscoord dy; // place overscript dy = aDesiredSize.ascent - mBoundingMetrics.ascent + bmOver.ascent - overSize.ascent; FinishReflowChild (overFrame, GetPresContext(), nsnull, overSize, dxOver, dy, 0); // place base dy = aDesiredSize.ascent - baseSize.ascent; FinishReflowChild (baseFrame, GetPresContext(), nsnull, baseSize, dxBase, dy, 0); // place underscript dy = aDesiredSize.ascent + mBoundingMetrics.descent - bmUnder.descent - underSize.ascent; FinishReflowChild (underFrame, GetPresContext(), nsnull, underSize, dxUnder, dy, 0); } return NS_OK; }
// 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(nsIRenderingContext& aRenderingContext, nsHeaderFooterEnum aHeaderFooter, PRInt32 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); PRInt32 indx; PRInt32 textWidth = 0; const PRUnichar* text = str.get(); PRInt32 len = (PRInt32)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, PRInt32(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.SetClipRect(aRect, nsClipCombine_kIntersect); nsLayoutUtils::DrawString(this, &aRenderingContext, str.get(), str.Length(), nsPoint(x, y + aAscent)); aRenderingContext.PopState(); } }
NS_IMETHODIMP nsTableCellFrame::Paint(nsPresContext* aPresContext, nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer, PRUint32 aFlags) { NS_ENSURE_TRUE(aPresContext, NS_ERROR_NULL_POINTER); PRBool isVisible; if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_FALSE, &isVisible)) && !isVisible) { return NS_OK; } PRBool paintChildren = PR_TRUE; if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) { const nsStyleBorder* myBorder = nsnull; const nsStylePadding* myPadding = nsnull; const nsStyleTableBorder* cellTableStyle = nsnull; const nsStyleVisibility* vis = GetStyleVisibility(); if (vis->IsVisible()) { myBorder = GetStyleBorder(); myPadding = GetStylePadding(); cellTableStyle = GetStyleTableBorder(); // draw the border & background only when there is content or showing empty cells if (NS_STYLE_TABLE_EMPTY_CELLS_HIDE != cellTableStyle->mEmptyCells || !GetContentEmpty()) { PaintUnderlay(*aPresContext, aRenderingContext, aDirtyRect, aFlags, *myBorder, *myPadding, *cellTableStyle); } // Paint outline nsRect rect(0, 0, mRect.width, mRect.height); const nsStyleOutline* myOutline = GetStyleOutline(); nsCSSRendering::PaintOutline(aPresContext, aRenderingContext, this, aDirtyRect, rect, *myBorder, *myOutline, mStyleContext, 0); const nsStyleBackground* myColor = GetStyleBackground(); DecorateForSelection(aPresContext, aRenderingContext,myColor); //ignore return value } paintChildren = !(aFlags & NS_PAINT_FLAG_TABLE_CELL_BG_PASS); //flags were for us; remove them for our children aFlags &= ~ (NS_PAINT_FLAG_TABLE_CELL_BG_PASS | NS_PAINT_FLAG_TABLE_BG_PAINT); } #ifdef DEBUG // for debug... if ((NS_FRAME_PAINT_LAYER_DEBUG == aWhichLayer) && GetShowFrameBorders()) { aRenderingContext.SetColor(NS_RGB(0, 0, 128)); aRenderingContext.DrawRect(0, 0, mRect.width, mRect.height); } #endif // paint the children unless we've been told not to if (paintChildren) { const nsStyleDisplay* disp = GetStyleDisplay(); // if the cell originates in a row and/or col that is collapsed, the // bottom and/or right portion of the cell is painted by translating // the rendering context. nsPoint offset; GetCollapseOffset(offset); PRBool pushed = PR_FALSE; if ((0 != offset.x) || (0 != offset.y)) { aRenderingContext.PushState(); pushed = PR_TRUE; aRenderingContext.Translate(offset.x, offset.y); aRenderingContext.SetClipRect(nsRect(-offset.x, -offset.y, mRect.width, mRect.height), nsClipCombine_kIntersect); } else { // XXXldb HIDDEN should really create a scrollframe, // but use |IsTableClip| here since it doesn't. if (disp->IsTableClip() || (HasPctOverHeight() && eCompatibility_NavQuirks == aPresContext->CompatibilityMode())) { aRenderingContext.PushState(); pushed = PR_TRUE; SetOverflowClipRect(aRenderingContext); } } PaintChildren(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer, aFlags); if (pushed) { aRenderingContext.PopState(); } } DO_GLOBAL_REFLOW_COUNT_DSP_J("nsTableCellFrame", &aRenderingContext, 0); return NS_OK; /*nsFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);*/ }
/* virtual */ nsresult nsMathMLmoverFrame::Place(nsIRenderingContext& aRenderingContext, PRBool aPlaceOrigin, nsHTMLReflowMetrics& aDesiredSize) { if ( NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(mEmbellishData.flags) && !NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)) { // place like superscript return nsMathMLmsupFrame::PlaceSuperScript(PresContext(), aRenderingContext, aPlaceOrigin, aDesiredSize, this, 0, nsPresContext::CSSPointsToAppUnits(0.5f)); } //////////////////////////////////// // Get the children's desired sizes nsBoundingMetrics bmBase, bmOver; nsHTMLReflowMetrics baseSize; nsHTMLReflowMetrics overSize; nsIFrame* overFrame = nsnull; nsIFrame* baseFrame = mFrames.FirstChild(); if (baseFrame) overFrame = baseFrame->GetNextSibling(); if (!baseFrame || !overFrame || overFrame->GetNextSibling()) { // report an error, encourage people to get their markups in order return ReflowError(aRenderingContext, aDesiredSize); } GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase); GetReflowAndBoundingMetricsFor(overFrame, overSize, bmOver); nscoord onePixel = nsPresContext::CSSPixelsToAppUnits(1); //////////////////// // Place Children aRenderingContext.SetFont(GetStyleFont()->mFont, PresContext()->GetUserFontSet()); nsCOMPtr<nsIFontMetrics> fm; aRenderingContext.GetFontMetrics(*getter_AddRefs(fm)); nscoord xHeight = 0; fm->GetXHeight (xHeight); nscoord ruleThickness; GetRuleThickness (aRenderingContext, fm, ruleThickness); // there are 2 different types of placement depending on // whether we want an accented overscript or not nscoord correction = 0; GetItalicCorrection (bmBase, correction); nscoord delta1 = 0; // gap between base and overscript nscoord delta2 = 0; // extra space above overscript if (!NS_MATHML_EMBELLISH_IS_ACCENTOVER(mEmbellishData.flags)) { // Rule 13a, App. G, TeXbook nscoord bigOpSpacing1, bigOpSpacing3, bigOpSpacing5, dummy; GetBigOpSpacings (fm, bigOpSpacing1, dummy, bigOpSpacing3, dummy, bigOpSpacing5); delta1 = NS_MAX(bigOpSpacing1, (bigOpSpacing3 - bmOver.descent)); delta2 = bigOpSpacing5; // XXX This is not a TeX rule... // delta1 (as computed above) can become really big when bmOver.descent is // negative, e.g., if the content is &OverBar. In such case, we use the height if (bmOver.descent < 0) delta1 = NS_MAX(bigOpSpacing1, (bigOpSpacing3 - (bmOver.ascent + bmOver.descent))); } else { // Rule 12, App. G, TeXbook // We are going to modify this rule to make it more general. // The idea behind Rule 12 in the TeXBook is to keep the accent // as close to the base as possible, while ensuring that the // distance between the *baseline* of the accent char and // the *baseline* of the base is atleast x-height. // The idea is that for normal use, we would like all the accents // on a line to line up atleast x-height above the baseline // if possible. // When the ascent of the base is >= x-height, // the baseline of the accent char is placed just above the base // (specifically, the baseline of the accent char is placed // above the baseline of the base by the ascent of the base). // For ease of implementation, // this assumes that the font-designer designs accents // in such a way that the bottom of the accent is atleast x-height // above its baseline, otherwise there will be collisions // with the base. Also there should be proper padding between // the bottom of the accent char and its baseline. // The above rule may not be obvious from a first // reading of rule 12 in the TeXBook !!! // The mathml <mover> tag can use accent chars that // do not follow this convention. So we modify TeX's rule // so that TeX's rule gets subsumed for accents that follow // TeX's convention, // while also allowing accents that do not follow the convention : // we try to keep the *bottom* of the accent char atleast x-height // from the baseline of the base char. we also slap on an extra // padding between the accent and base chars. delta1 = ruleThickness + onePixel/2; // we have at least the padding if (bmBase.ascent < xHeight) { // also ensure at least x-height above the baseline of the base delta1 += xHeight - bmBase.ascent; } delta2 = ruleThickness; } // empty over? if (!(bmOver.ascent + bmOver.descent)) delta1 = 0; nscoord dxBase, dxOver = 0; // Ad-hoc - This is to override fonts which have ready-made _accent_ // glyphs with negative lbearing and rbearing. We want to position // the overscript ourselves nscoord overWidth = bmOver.width; if (!overWidth && (bmOver.rightBearing - bmOver.leftBearing > 0)) { overWidth = bmOver.rightBearing - bmOver.leftBearing; dxOver = -bmOver.leftBearing; } if (NS_MATHML_EMBELLISH_IS_ACCENTOVER(mEmbellishData.flags)) { mBoundingMetrics.width = bmBase.width; dxOver += correction + (mBoundingMetrics.width - overWidth)/2; } else { mBoundingMetrics.width = NS_MAX(bmBase.width, overWidth); dxOver += correction/2 + (mBoundingMetrics.width - overWidth)/2; } dxBase = (mBoundingMetrics.width - bmBase.width) / 2; mBoundingMetrics.ascent = bmOver.ascent + bmOver.descent + delta1 + bmBase.ascent; mBoundingMetrics.descent = bmBase.descent; mBoundingMetrics.leftBearing = NS_MIN(dxBase + bmBase.leftBearing, dxOver + bmOver.leftBearing); mBoundingMetrics.rightBearing = NS_MAX(dxBase + bmBase.rightBearing, dxOver + bmOver.rightBearing); aDesiredSize.ascent = NS_MAX(mBoundingMetrics.ascent + delta2, overSize.ascent + bmOver.descent + delta1 + bmBase.ascent); aDesiredSize.height = aDesiredSize.ascent + baseSize.height - baseSize.ascent; aDesiredSize.width = mBoundingMetrics.width; aDesiredSize.mBoundingMetrics = mBoundingMetrics; mReference.x = 0; mReference.y = aDesiredSize.ascent; if (aPlaceOrigin) { // place base nscoord dy = aDesiredSize.ascent - baseSize.ascent; FinishReflowChild (baseFrame, PresContext(), nsnull, baseSize, dxBase, dy, 0); // place overscript dy = aDesiredSize.ascent - mBoundingMetrics.ascent + bmOver.ascent - overSize.ascent; FinishReflowChild (overFrame, PresContext(), nsnull, overSize, dxOver, dy, 0); } return NS_OK; }
// exported routine that both munderover and msubsup share. // munderover uses this when movablelimits is set. nsresult nsMathMLmsubsupFrame::PlaceSubSupScript(nsPresContext* aPresContext, nsIRenderingContext& aRenderingContext, PRBool aPlaceOrigin, nsHTMLReflowMetrics& aDesiredSize, nsMathMLContainerFrame* aFrame, nscoord aUserSubScriptShift, nscoord aUserSupScriptShift, nscoord aScriptSpace) { // force the scriptSpace to be atleast 1 pixel nscoord onePixel = nsPresContext::CSSPixelsToAppUnits(1); aScriptSpace = PR_MAX(onePixel, aScriptSpace); //////////////////////////////////// // Get the children's desired sizes nsHTMLReflowMetrics baseSize; nsHTMLReflowMetrics subScriptSize; nsHTMLReflowMetrics supScriptSize; nsBoundingMetrics bmBase, bmSubScript, bmSupScript; nsIFrame* subScriptFrame = nsnull; nsIFrame* supScriptFrame = nsnull; nsIFrame* baseFrame = aFrame->GetFirstChild(nsnull); if (baseFrame) subScriptFrame = baseFrame->GetNextSibling(); if (subScriptFrame) supScriptFrame = subScriptFrame->GetNextSibling(); if (!baseFrame || !subScriptFrame || !supScriptFrame || supScriptFrame->GetNextSibling()) { // report an error, encourage people to get their markups in order return aFrame->ReflowError(aRenderingContext, aDesiredSize); } GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase); GetReflowAndBoundingMetricsFor(subScriptFrame, subScriptSize, bmSubScript); GetReflowAndBoundingMetricsFor(supScriptFrame, supScriptSize, bmSupScript); // get the subdrop from the subscript font nscoord subDrop; GetSubDropFromChild(subScriptFrame, subDrop); // parameter v, Rule 18a, App. G, TeXbook nscoord minSubScriptShift = bmBase.descent + subDrop; // get the supdrop from the supscript font nscoord supDrop; GetSupDropFromChild(supScriptFrame, supDrop); // parameter u, Rule 18a, App. G, TeXbook nscoord minSupScriptShift = bmBase.ascent - supDrop; ////////////////// // Place Children ////////////////// ////////////////////////////////////////////////// // Get subscript shift // slightly different from nsMathMLmsubFrame.cpp ////////////////////////////////////////////////// // subScriptShift{1,2} // = minimum amount to shift the subscript down // = sub{1,2} in TeXbook // subScriptShift1 = subscriptshift attribute * x-height nscoord subScriptShift1, subScriptShift2; aRenderingContext.SetFont(baseFrame->GetStyleFont()->mFont, nsnull, aPresContext->GetUserFontSet()); nsCOMPtr<nsIFontMetrics> fm; aRenderingContext.GetFontMetrics(*getter_AddRefs(fm)); // get x-height (an ex) nscoord xHeight; fm->GetXHeight (xHeight); nscoord ruleSize; GetRuleThickness (aRenderingContext, fm, ruleSize); // Get subScriptShift{1,2} default from font GetSubScriptShifts (fm, subScriptShift1, subScriptShift2); if (0 < aUserSubScriptShift) { // the user has set the subscriptshift attribute float scaler = ((float) subScriptShift2) / subScriptShift1; subScriptShift1 = PR_MAX(subScriptShift1, aUserSubScriptShift); subScriptShift2 = NSToCoordRound(scaler * subScriptShift1); } // get a tentative value for subscriptshift // Rule 18d, App. G, TeXbook nscoord subScriptShift = PR_MAX(minSubScriptShift,PR_MAX(subScriptShift1,subScriptShift2)); ////////////////////////////////////////////////// // Get supscript shift // same code from nsMathMLmsupFrame.cpp ////////////////////////////////////////////////// // get min supscript shift limit from x-height // = d(x) + 1/4 * sigma_5, Rule 18c, App. G, TeXbook nscoord minShiftFromXHeight = (nscoord) (bmSupScript.descent + (1.0f/4.0f) * xHeight); // supScriptShift{1,2,3} // = minimum amount to shift the supscript up // = sup{1,2,3} in TeX // supScriptShift1 = superscriptshift attribute * x-height // Note that there are THREE values for supscript shifts depending // on the current style nscoord supScriptShift1, supScriptShift2, supScriptShift3; // Set supScriptShift{1,2,3} default from font GetSupScriptShifts (fm, supScriptShift1, supScriptShift2, supScriptShift3); if (0 < aUserSupScriptShift) { // the user has set the superscriptshift attribute float scaler2 = ((float) supScriptShift2) / supScriptShift1; float scaler3 = ((float) supScriptShift3) / supScriptShift1; supScriptShift1 = PR_MAX(supScriptShift1, aUserSupScriptShift); supScriptShift2 = NSToCoordRound(scaler2 * supScriptShift1); supScriptShift3 = NSToCoordRound(scaler3 * supScriptShift1); } // get sup script shift depending on current script level and display style // Rule 18c, App. G, TeXbook nscoord supScriptShift; nsPresentationData presentationData; aFrame->GetPresentationData(presentationData); if ( aFrame->GetStyleFont()->mScriptLevel == 0 && NS_MATHML_IS_DISPLAYSTYLE(presentationData.flags) && !NS_MATHML_IS_COMPRESSED(presentationData.flags)) { // Style D in TeXbook supScriptShift = supScriptShift1; } else if (NS_MATHML_IS_COMPRESSED(presentationData.flags)) { // Style C' in TeXbook = D',T',S',SS' supScriptShift = supScriptShift3; } else { // everything else = T,S,SS supScriptShift = supScriptShift2; } // get tentative value for superscriptshift // Rule 18c, App. G, TeXbook supScriptShift = PR_MAX(minSupScriptShift,PR_MAX(supScriptShift,minShiftFromXHeight)); ////////////////////////////////////////////////// // Negotiate between supScriptShift and subScriptShift // so that there will be enough gap between them // Rule 18e, App. G, TeXbook ////////////////////////////////////////////////// nscoord gap = (supScriptShift - bmSupScript.descent) - (bmSubScript.ascent - subScriptShift); if (gap < 4.0f * ruleSize) { // adjust subScriptShift to get a gap of (4.0 * ruleSize) subScriptShift += NSToCoordRound ((4.0f * ruleSize) - gap); } // next we want to ensure that the bottom of the superscript // will be > (4/5) * x-height above baseline gap = NSToCoordRound ((4.0f/5.0f) * xHeight - (supScriptShift - bmSupScript.descent)); if (gap > 0) { supScriptShift += gap; subScriptShift -= gap; } ////////////////////////////////////////////////// // Do the Placing ////////////////////////////////////////////////// // get bounding box for base + subscript + superscript nsBoundingMetrics boundingMetrics; boundingMetrics.ascent = PR_MAX(bmBase.ascent, (bmSupScript.ascent + supScriptShift)); boundingMetrics.descent = PR_MAX(bmBase.descent, (bmSubScript.descent + subScriptShift)); // leave aScriptSpace after both super/subscript // add italicCorrection between base and superscript // add "a little to spare" as well (see TeXbook Ch.11, p.64), as we // estimate the italic creation ourselves and it isn't the same as TeX nscoord italicCorrection; GetItalicCorrection(bmBase, italicCorrection); italicCorrection += onePixel; boundingMetrics.width = bmBase.width + aScriptSpace + PR_MAX((italicCorrection + bmSupScript.width), bmSubScript.width); boundingMetrics.leftBearing = bmBase.leftBearing; boundingMetrics.rightBearing = bmBase.width + PR_MAX((italicCorrection + bmSupScript.rightBearing), bmSubScript.rightBearing); aFrame->SetBoundingMetrics(boundingMetrics); // reflow metrics aDesiredSize.ascent = PR_MAX(baseSize.ascent, PR_MAX(subScriptSize.ascent - subScriptShift, supScriptSize.ascent + supScriptShift)); aDesiredSize.height = aDesiredSize.ascent + PR_MAX(baseSize.height - baseSize.ascent, PR_MAX(subScriptSize.height - subScriptSize.ascent + subScriptShift, supScriptSize.height - subScriptSize.ascent - supScriptShift)); aDesiredSize.width = boundingMetrics.width; aDesiredSize.mBoundingMetrics = boundingMetrics; aFrame->SetReference(nsPoint(0, aDesiredSize.ascent)); if (aPlaceOrigin) { nscoord dx, dy; // now place the base ... dx = 0; dy = aDesiredSize.ascent - baseSize.ascent; FinishReflowChild(baseFrame, aPresContext, nsnull, baseSize, dx, dy, 0); // ... and subscript dx = bmBase.width; dy = aDesiredSize.ascent - (subScriptSize.ascent - subScriptShift); FinishReflowChild(subScriptFrame, aPresContext, nsnull, subScriptSize, dx, dy, 0); // ... and the superscript dx = bmBase.width + italicCorrection; dy = aDesiredSize.ascent - (supScriptSize.ascent + supScriptShift); FinishReflowChild(supScriptFrame, aPresContext, nsnull, supScriptSize, dx, dy, 0); } return NS_OK; }