diff --git a/mozilla/content/html/content/src/nsHTMLAtoms.cpp b/mozilla/content/html/content/src/nsHTMLAtoms.cpp index 616124cef9d..15a5ee9687b 100644 --- a/mozilla/content/html/content/src/nsHTMLAtoms.cpp +++ b/mozilla/content/html/content/src/nsHTMLAtoms.cpp @@ -83,6 +83,7 @@ nsIAtom* nsHTMLAtoms::embed; nsIAtom* nsHTMLAtoms::encoding; nsIAtom* nsHTMLAtoms::enctype; nsIAtom* nsHTMLAtoms::face; +nsIAtom* nsHTMLAtoms::fieldset; nsIAtom* nsHTMLAtoms::font; nsIAtom* nsHTMLAtoms::fontWeight; nsIAtom* nsHTMLAtoms::_for; @@ -121,6 +122,7 @@ nsIAtom* nsHTMLAtoms::link; nsIAtom* nsHTMLAtoms::left; nsIAtom* nsHTMLAtoms::leftpadding; nsIAtom* nsHTMLAtoms::length; +nsIAtom* nsHTMLAtoms::legend; nsIAtom* nsHTMLAtoms::longdesc; nsIAtom* nsHTMLAtoms::lowsrc; nsIAtom* nsHTMLAtoms::marginheight; @@ -294,6 +296,7 @@ void nsHTMLAtoms::AddrefAtoms() encoding = NS_NewAtom("ENCODING"); enctype = NS_NewAtom("ENCTYPE"); face = NS_NewAtom("FACE"); + fieldset = NS_NewAtom("FIELDSET"); font = NS_NewAtom("FONT"); fontWeight = NS_NewAtom("FONT-WEIGHT"); _for = NS_NewAtom("FOR"); @@ -331,6 +334,7 @@ void nsHTMLAtoms::AddrefAtoms() link = NS_NewAtom("LINK"); left = NS_NewAtom("LEFT"); leftpadding = NS_NewAtom("LEFTPADDING"); + legend = NS_NewAtom("LEGEND"); length = NS_NewAtom("LENGTH"); lowsrc = NS_NewAtom("LOWSRC"); marginheight = NS_NewAtom("MARGINHEIGHT"); @@ -501,6 +505,7 @@ void nsHTMLAtoms::ReleaseAtoms() NS_RELEASE(embed); NS_RELEASE(encoding); NS_RELEASE(face); + NS_RELEASE(fieldset); NS_RELEASE(font); NS_RELEASE(fontWeight); NS_RELEASE(_for); @@ -535,6 +540,7 @@ void nsHTMLAtoms::ReleaseAtoms() NS_RELEASE(link); NS_RELEASE(left); NS_RELEASE(leftpadding); + NS_RELEASE(legend); NS_RELEASE(length); NS_RELEASE(lowsrc); NS_RELEASE(marginheight); diff --git a/mozilla/content/html/content/src/nsHTMLAtoms.h b/mozilla/content/html/content/src/nsHTMLAtoms.h index b5c635c3d88..c65e06d5233 100644 --- a/mozilla/content/html/content/src/nsHTMLAtoms.h +++ b/mozilla/content/html/content/src/nsHTMLAtoms.h @@ -107,6 +107,7 @@ public: static nsIAtom* enctype; static nsIAtom* face; + static nsIAtom* fieldset; static nsIAtom* font; static nsIAtom* fontWeight; static nsIAtom* _for; @@ -148,6 +149,7 @@ public: static nsIAtom* link; static nsIAtom* left; static nsIAtom* leftpadding; + static nsIAtom* legend; static nsIAtom* length; static nsIAtom* longdesc; static nsIAtom* lowsrc; diff --git a/mozilla/content/html/content/src/nsHTMLFieldSetElement.cpp b/mozilla/content/html/content/src/nsHTMLFieldSetElement.cpp index b52b1aa4967..4961456550f 100644 --- a/mozilla/content/html/content/src/nsHTMLFieldSetElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLFieldSetElement.cpp @@ -180,16 +180,28 @@ nsHTMLFieldSetElement::GetForm(nsIDOMHTMLFormElement** aForm) return result; } +// An important assumption is that if aForm is null, the previous mForm will not be released +// This allows nsHTMLFormElement to deal with circular references. NS_IMETHODIMP nsHTMLFieldSetElement::SetForm(nsIDOMHTMLFormElement* aForm) { + nsresult result = NS_OK; if (nsnull == aForm) { mForm = nsnull; return NS_OK; } else { NS_IF_RELEASE(mForm); - return aForm->QueryInterface(kIFormIID, (void**)&mForm); + nsIFormControl* formControl = nsnull; + result = QueryInterface(kIFormControlIID, (void**)&formControl); + if ((NS_OK == result) && formControl) { + result = aForm->QueryInterface(kIFormIID, (void**)&mForm); // keep the ref + if ((NS_OK == result) && mForm) { + mForm->AddElement(formControl); + } + NS_RELEASE(formControl); + } } + return result; } NS_IMETHODIMP diff --git a/mozilla/content/html/document/src/nsHTMLContentSink.cpp b/mozilla/content/html/document/src/nsHTMLContentSink.cpp index fcc63bc5532..fd57765d43b 100644 --- a/mozilla/content/html/document/src/nsHTMLContentSink.cpp +++ b/mozilla/content/html/document/src/nsHTMLContentSink.cpp @@ -522,6 +522,10 @@ MakeContentObject(nsHTMLTag aNodeType, case eHTMLTag_embed: rv = NS_NewHTMLEmbedElement(aResult, aAtom); break; + case eHTMLTag_fieldset: + rv = NS_NewHTMLFieldSetElement(aResult, aAtom); + SetForm(*aResult, aForm); + break; case eHTMLTag_font: rv = NS_NewHTMLFontElement(aResult, aAtom); break; diff --git a/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp b/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp index 014a0cc176b..c60e5e71758 100644 --- a/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp +++ b/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp @@ -1208,6 +1208,14 @@ HTMLStyleSheetImpl::ConstructFrameByTag(nsIPresContext* aPresContext, else if (nsHTMLAtoms::embed == aTag) { rv = NS_NewObjectFrame(aContent, aParentFrame, aNewFrame); } + else if (nsHTMLAtoms::fieldset == aTag) { + rv = NS_NewFieldSetFrame(aContent, aParentFrame, aNewFrame); + processChildren = PR_TRUE; + } + else if (nsHTMLAtoms::legend == aTag) { + rv = NS_NewLegendFrame(aContent, aParentFrame, aNewFrame); + processChildren = PR_TRUE; + } else if (nsHTMLAtoms::object == aTag) { rv = NS_NewObjectFrame(aContent, aParentFrame, aNewFrame); // processChildren = PR_TRUE; diff --git a/mozilla/content/shared/public/nsHTMLAtoms.h b/mozilla/content/shared/public/nsHTMLAtoms.h index b5c635c3d88..c65e06d5233 100644 --- a/mozilla/content/shared/public/nsHTMLAtoms.h +++ b/mozilla/content/shared/public/nsHTMLAtoms.h @@ -107,6 +107,7 @@ public: static nsIAtom* enctype; static nsIAtom* face; + static nsIAtom* fieldset; static nsIAtom* font; static nsIAtom* fontWeight; static nsIAtom* _for; @@ -148,6 +149,7 @@ public: static nsIAtom* link; static nsIAtom* left; static nsIAtom* leftpadding; + static nsIAtom* legend; static nsIAtom* length; static nsIAtom* longdesc; static nsIAtom* lowsrc; diff --git a/mozilla/content/shared/src/nsHTMLAtoms.cpp b/mozilla/content/shared/src/nsHTMLAtoms.cpp index 616124cef9d..15a5ee9687b 100644 --- a/mozilla/content/shared/src/nsHTMLAtoms.cpp +++ b/mozilla/content/shared/src/nsHTMLAtoms.cpp @@ -83,6 +83,7 @@ nsIAtom* nsHTMLAtoms::embed; nsIAtom* nsHTMLAtoms::encoding; nsIAtom* nsHTMLAtoms::enctype; nsIAtom* nsHTMLAtoms::face; +nsIAtom* nsHTMLAtoms::fieldset; nsIAtom* nsHTMLAtoms::font; nsIAtom* nsHTMLAtoms::fontWeight; nsIAtom* nsHTMLAtoms::_for; @@ -121,6 +122,7 @@ nsIAtom* nsHTMLAtoms::link; nsIAtom* nsHTMLAtoms::left; nsIAtom* nsHTMLAtoms::leftpadding; nsIAtom* nsHTMLAtoms::length; +nsIAtom* nsHTMLAtoms::legend; nsIAtom* nsHTMLAtoms::longdesc; nsIAtom* nsHTMLAtoms::lowsrc; nsIAtom* nsHTMLAtoms::marginheight; @@ -294,6 +296,7 @@ void nsHTMLAtoms::AddrefAtoms() encoding = NS_NewAtom("ENCODING"); enctype = NS_NewAtom("ENCTYPE"); face = NS_NewAtom("FACE"); + fieldset = NS_NewAtom("FIELDSET"); font = NS_NewAtom("FONT"); fontWeight = NS_NewAtom("FONT-WEIGHT"); _for = NS_NewAtom("FOR"); @@ -331,6 +334,7 @@ void nsHTMLAtoms::AddrefAtoms() link = NS_NewAtom("LINK"); left = NS_NewAtom("LEFT"); leftpadding = NS_NewAtom("LEFTPADDING"); + legend = NS_NewAtom("LEGEND"); length = NS_NewAtom("LENGTH"); lowsrc = NS_NewAtom("LOWSRC"); marginheight = NS_NewAtom("MARGINHEIGHT"); @@ -501,6 +505,7 @@ void nsHTMLAtoms::ReleaseAtoms() NS_RELEASE(embed); NS_RELEASE(encoding); NS_RELEASE(face); + NS_RELEASE(fieldset); NS_RELEASE(font); NS_RELEASE(fontWeight); NS_RELEASE(_for); @@ -535,6 +540,7 @@ void nsHTMLAtoms::ReleaseAtoms() NS_RELEASE(link); NS_RELEASE(left); NS_RELEASE(leftpadding); + NS_RELEASE(legend); NS_RELEASE(length); NS_RELEASE(lowsrc); NS_RELEASE(marginheight); diff --git a/mozilla/layout/base/nsCSSRendering.cpp b/mozilla/layout/base/nsCSSRendering.cpp index cfdc9bf8d98..d1b0b11b003 100644 --- a/mozilla/layout/base/nsCSSRendering.cpp +++ b/mozilla/layout/base/nsCSSRendering.cpp @@ -36,6 +36,88 @@ #define DASH_LENGTH 3 //3 times longer than dot +// Draw a line, skipping that portion which crosses aGap. aGap defines a rectangle gap +// This services fieldset legends and only works for coords defining horizontal lines. +void nsCSSRendering::DrawLine (nsIRenderingContext& aContext, + nscoord aX1, nscoord aY1, nscoord aX2, nscoord aY2, + nsRect* aGap) +{ + if (nsnull == aGap) { + aContext.DrawLine(aX1, aY1, aX2, aY2); + } else { + nscoord x1 = (aX1 < aX2) ? aX1 : aX2; + nscoord x2 = (aX1 < aX2) ? aX2 : aX1; + nsPoint gapUpperRight(aGap->x + aGap->width, aGap->y); + nsPoint gapLowerRight(aGap->x + aGap->width, aGap->y + aGap->height); + if ((aGap->y <= aY1) && (gapLowerRight.y >= aY2)) { + if ((aGap->x > x1) && (aGap->x < x2)) { + aContext.DrawLine(x1, aY1, aGap->x, aY1); + } + if ((gapLowerRight.x > x1) && (gapLowerRight.x < x2)) { + aContext.DrawLine(gapUpperRight.x, aY2, x2, aY2); + } + } else { + aContext.DrawLine(aX1, aY1, aX2, aY2); + } + } +} + +// Fill a polygon, skipping that portion which crosses aGap. aGap defines a rectangle gap +// This services fieldset legends and only works for points defining a horizontal rectangle +void nsCSSRendering::FillPolygon (nsIRenderingContext& aContext, + const nsPoint aPoints[], + PRInt32 aNumPoints, + nsRect* aGap) +{ + if (nsnull == aGap) { + aContext.FillPolygon(aPoints, aNumPoints); + } else if (4 == aNumPoints) { + nsPoint gapUpperRight(aGap->x + aGap->width, aGap->y); + nsPoint gapLowerRight(aGap->x + aGap->width, aGap->y + aGap->height); + + // sort the 4 points by x + nsPoint points[4]; + for (int i = 0; i < 4; i++) { + points[i] = aPoints[i]; + } + for (i = 0; i < 3; i++) { + for (int j = i+1; j < 4; j++) { + if (points[j].x < points[i].x) { + nsPoint swap = points[i]; + points[i] = points[j]; + points[j] = swap; + } + } + } + + nsPoint upperLeft = (points[0].y <= points[1].y) ? points[0] : points[1]; + nsPoint lowerLeft = (points[0].y <= points[1].y) ? points[1] : points[0]; + nsPoint upperRight = (points[2].y <= points[3].y) ? points[2] : points[3]; + nsPoint lowerRight = (points[2].y <= points[3].y) ? points[3] : points[2]; + + + if ((aGap->y <= upperLeft.y) && (gapLowerRight.y >= lowerRight.y)) { + if ((aGap->x > upperLeft.x) && (aGap->x < upperRight.x)) { + nsPoint leftRect[4]; + leftRect[0] = upperLeft; + leftRect[1] = nsPoint(aGap->x, upperLeft.y); + leftRect[2] = nsPoint(aGap->x, lowerLeft.y); + leftRect[3] = lowerLeft; + aContext.FillPolygon(leftRect, 4); + } + if ((gapUpperRight.x > upperLeft.x) && (gapUpperRight.x < upperRight.x)) { + nsPoint rightRect[4]; + rightRect[0] = nsPoint(gapUpperRight.x, upperRight.y); + rightRect[1] = upperRight; + rightRect[2] = lowerRight; + rightRect[3] = nsPoint(gapLowerRight.x, lowerRight.y); + aContext.FillPolygon(rightRect, 4); + } + } else { + aContext.FillPolygon(aPoints, aNumPoints); + } + } +} /** * Make a bevel color @@ -275,7 +357,8 @@ void nsCSSRendering::DrawSide(nsIRenderingContext& aContext, const nsRect& borderOutside, const nsRect& borderInside, PRBool printing, - nscoord twipsPerPixel) + nscoord twipsPerPixel, + nsRect* aGap) { nsPoint theSide[MAX_POLY_POINTS]; nscolor theColor = borderColors[whichSide]; @@ -296,9 +379,11 @@ void nsCSSRendering::DrawSide(nsIRenderingContext& aContext, BORDER_INSIDE, 0.5f, twipsPerPixel); aContext.SetColor ( MakeBevelColor (whichSide, theStyle, theColor, printing)); if (2 == np) { - aContext.DrawLine (theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y); + //aContext.DrawLine (theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y); + DrawLine (aContext, theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y, aGap); } else { - aContext.FillPolygon (theSide, np); + //aContext.FillPolygon (theSide, np); + FillPolygon (aContext, theSide, np, aGap); } np = MakeSide (theSide, aContext, whichSide, borderOutside, borderInside, BORDER_OUTSIDE, 0.5f, twipsPerPixel); @@ -307,9 +392,11 @@ void nsCSSRendering::DrawSide(nsIRenderingContext& aContext, ? NS_STYLE_BORDER_STYLE_GROOVE : NS_STYLE_BORDER_STYLE_RIDGE, theColor,printing)); if (2 == np) { - aContext.DrawLine (theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y); + //aContext.DrawLine (theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y); + DrawLine (aContext, theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y, aGap); } else { - aContext.FillPolygon (theSide, np); + //aContext.FillPolygon (theSide, np); + FillPolygon (aContext, theSide, np, aGap); } break; @@ -318,9 +405,11 @@ void nsCSSRendering::DrawSide(nsIRenderingContext& aContext, BORDER_FULL, 1.0f, twipsPerPixel); aContext.SetColor (borderColors[whichSide]); if (2 == np) { - aContext.DrawLine (theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y); + //aContext.DrawLine (theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y); + DrawLine (aContext, theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y, aGap); } else { - aContext.FillPolygon (theSide, np); + //aContext.FillPolygon (theSide, np); + FillPolygon (aContext, theSide, np, aGap); } break; @@ -329,16 +418,20 @@ void nsCSSRendering::DrawSide(nsIRenderingContext& aContext, BORDER_INSIDE, 0.333333f, twipsPerPixel); aContext.SetColor (borderColors[whichSide]); if (2 == np) { - aContext.DrawLine (theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y); + //aContext.DrawLine (theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y); + DrawLine (aContext, theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y, aGap); } else { - aContext.FillPolygon (theSide, np); - } + //aContext.FillPolygon (theSide, np); + FillPolygon (aContext, theSide, np, aGap); + } np = MakeSide (theSide, aContext, whichSide, borderOutside, borderInside, BORDER_OUTSIDE, 0.333333f, twipsPerPixel); if (2 == np) { - aContext.DrawLine (theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y); + //aContext.DrawLine (theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y); + DrawLine (aContext, theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y, aGap); } else { - aContext.FillPolygon (theSide, np); + //aContext.FillPolygon (theSide, np); + FillPolygon (aContext, theSide, np, aGap); } break; @@ -348,9 +441,11 @@ void nsCSSRendering::DrawSide(nsIRenderingContext& aContext, BORDER_FULL, 1.0f, twipsPerPixel); aContext.SetColor ( MakeBevelColor (whichSide, theStyle, theColor,printing)); if (2 == np) { - aContext.DrawLine (theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y); + //aContext.DrawLine (theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y); + DrawLine (aContext, theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y, aGap); } else { - aContext.FillPolygon (theSide, np); + //aContext.FillPolygon (theSide, np); + FillPolygon (aContext, theSide, np, aGap); } break; } @@ -366,7 +461,8 @@ void nsCSSRendering::DrawDashedSides(PRIntn startSide, const nscolor borderColors[], const nsRect& borderOutside, const nsRect& borderInside, - PRIntn aSkipSides) + PRIntn aSkipSides, + nsRect* aGap) { PRIntn dashLength; nsRect dashRect, firstRect, currRect; @@ -595,7 +691,8 @@ void nsCSSRendering::PaintBorder(nsIPresContext& aPresContext, const nsRect& aDirtyRect, const nsRect& aBounds, const nsStyleSpacing& aStyle, - PRIntn aSkipSides) + PRIntn aSkipSides, + nsRect* aGap) { PRIntn cnt; nsMargin border; @@ -624,7 +721,7 @@ void nsCSSRendering::PaintBorder(nsIPresContext& aPresContext, // Draw the dashed/dotted lines first DrawDashedSides(cnt, aRenderingContext, aStyle.mBorderStyle, aStyle.mBorderColor, inside, outside, - aSkipSides); + aSkipSides, aGap); } // Draw all the other sides @@ -632,19 +729,19 @@ void nsCSSRendering::PaintBorder(nsIPresContext& aPresContext, if (0 == (aSkipSides & (1<mDisplay); + + if (mInline) { + NS_NewInlineFrame(mContent, this, mFirstChild); + } else { + NS_NewBodyFrame(mContent, this, mFirstChild, PR_FALSE); + } + mContentFrame = mFirstChild; + + // Resolve style and set the style context + nsIStyleContext* styleContext = aPresContext.ResolveStyleContextFor(mContent, this); + mFirstChild->SetStyleContext(&aPresContext, styleContext); + NS_RELEASE(styleContext); + + nsIFrame* newChildList = aChildList; + + mFirstChild->SetNextSibling(nsnull); + // Set the geometric and content parent for each of the child frames. + // The legend is handled differently and removed from aChildList + nsIFrame* lastFrame = nsnull; + for (nsIFrame* frame = aChildList; nsnull != frame; frame->GetNextSibling(frame)) { + nsIFrame* legendFrame = nsnull; + nsresult result = frame->QueryInterface(kLegendFrameCID, (void**)&legendFrame); + if ((NS_OK == result) && legendFrame) { + nsIFrame* nextFrame; + frame->GetNextSibling(nextFrame); + if (lastFrame) { + lastFrame->SetNextSibling(nextFrame); + } else { + newChildList = nextFrame; + } + frame->SetGeometricParent(this); + frame->SetContentParent(this); + mFirstChild->SetNextSibling(frame); + mLegendFrame = frame; + mLegendFrame->SetNextSibling(nsnull); + } else { + frame->SetGeometricParent(mFirstChild); + frame->SetContentParent(mFirstChild); + } + lastFrame = frame; + } + + // Queue up the frames for the content frame + return mFirstChild->Init(aPresContext, newChildList); +} + +// this is identical to nsHTMLContainerFrame::Paint except for the background and border. +NS_IMETHODIMP +nsFieldSetFrame::Paint(nsIPresContext& aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect) +{ + // Paint our background and border + const nsStyleDisplay* disp = + (const nsStyleDisplay*)mStyleContext->GetStyleData(eStyleStruct_Display); + + if (disp->mVisible && mRect.width && mRect.height) { + PRIntn skipSides = GetSkipSides(); + const nsStyleColor* color = + (const nsStyleColor*)mStyleContext->GetStyleData(eStyleStruct_Color); + const nsStyleSpacing* spacing = + (const nsStyleSpacing*)mStyleContext->GetStyleData(eStyleStruct_Spacing); + + nsRect backgroundRect(0, 0, mRect.width, mRect.height); + // XXX our parent doesn't account for top and bottom margins yet, if we are inline + if (mInline) { + nsMargin margin; + spacing->CalcMarginFor(this, margin); + nsRect rect(0, mTopBorderOffset, mRect.width, mRect.height - margin.top - + margin.bottom - mTopBorderOffset); + nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this, + aDirtyRect, rect, *color, 0, 0); + nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this, + aDirtyRect, rect, *spacing, skipSides, &mTopBorderGap); + } else { + nsRect rect(0, mTopBorderOffset, mRect.width, mRect.height - mTopBorderOffset); + nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this, + aDirtyRect, rect, *color, 0, 0); + nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this, + aDirtyRect, rect, *spacing, skipSides, &mTopBorderGap); + } + } + + PaintChildren(aPresContext, aRenderingContext, aDirtyRect); + + if (nsIFrame::GetShowFrameBorders()) { + nsIView* view; + GetView(view); + if (nsnull != view) { + aRenderingContext.SetColor(NS_RGB(0,0,255)); + } + else { + aRenderingContext.SetColor(NS_RGB(255,0,0)); + } + aRenderingContext.DrawRect(0, 0, mRect.width, mRect.height); + } + return NS_OK; +} + +void +nsFieldSetFrame::SetMaxElementSize(nsSize& maxSize, nsSize* aSize) +{ + if (aSize) { + maxSize.width = (maxSize.width >= aSize->width) ? maxSize.width : aSize->width; + maxSize.height = (maxSize.height >= aSize->width) ? maxSize.height : aSize->height; + } +} + +// XXX currently only supports legend align=left,center,right +#define MIN_TOP_BORDER 10 +NS_IMETHODIMP +nsFieldSetFrame::Reflow(nsIPresContext& aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus) +{ + nsSize availSize(aReflowState.maxSize); + float p2t = aPresContext.GetPixelsToTwips(); + const PRInt32 minTopBorder = NSIntPixelsToTwips(MIN_TOP_BORDER, p2t); + + const nsStyleSpacing* spacing = + (const nsStyleSpacing*)mStyleContext->GetStyleData(eStyleStruct_Spacing); + + nsMargin margin; + spacing->CalcMarginFor(this, margin); + + nsMargin border; + nsMargin padding; + spacing->CalcBorderFor(this, border); + spacing->CalcPaddingFor(this, padding); + nsMargin borderPadding = border + padding; + + nsMargin legendMargin; + if (mLegendFrame) { + nsIStyleContext* legendSC = nsnull; + mLegendFrame->GetStyleContext(&aPresContext, legendSC); + if (legendSC) { + const nsStyleSpacing* legendSpacing = + (const nsStyleSpacing*)legendSC->GetStyleData(eStyleStruct_Spacing); + legendSpacing->CalcMarginFor(mLegendFrame, legendMargin); + NS_RELEASE(legendSC); + } + } + + // reduce available space by border, padding, etc. if we're in a constrained situation + nscoord horTaken = borderPadding.left + borderPadding.right + (2 * minTopBorder) + + legendMargin.left + legendMargin.right; + nscoord verTaken = padding.top + borderPadding.bottom + legendMargin.top + legendMargin.bottom; + if (NS_UNCONSTRAINEDSIZE != availSize.width) + availSize.width -= horTaken; + if (NS_UNCONSTRAINEDSIZE != availSize.height) { + // XXX this assumes that the legend is taller than the top border width + availSize.height -= verTaken; + if (mInline) { // XXX parents don't account for inline top, bottom margins yet + availSize.height -= margin.top; + } + } + if (availSize.height < 0) + availSize.height = 1; + + nsSize maxElementSize(0,0); + nsIHTMLReflow* htmlReflow = nsnull; + + // Try to reflow the legend into the available space. It might not fit + nsSize legendSize(0,0); + if (mLegendFrame) { + nsHTMLReflowState legendReflowState(mLegendFrame, aReflowState, availSize); + ReflowChild(mLegendFrame, aPresContext, aDesiredSize, legendReflowState, aStatus); + + legendSize.width = aDesiredSize.width; + legendSize.height = aDesiredSize.height; + + // The legend didn't fit + if ((NS_UNCONSTRAINEDSIZE != availSize.width) && + (availSize.width < aDesiredSize.width + legendMargin.left + legendMargin.right)) { + availSize.width = aDesiredSize.width + horTaken; + } + if ((NS_UNCONSTRAINEDSIZE != availSize.height) && (availSize.height < aDesiredSize.height)) { + availSize.height = 0; + } else { + availSize.height -= aDesiredSize.height; + } + SetMaxElementSize(maxElementSize, aDesiredSize.maxElementSize); + } + + PRBool needAnotherLegendReflow = PR_FALSE; + + // Try to reflow the content frame into the available space. It might not fit + nsSize contentSize(0,0); + nsHTMLReflowState contentReflowState(mContentFrame, aReflowState, availSize); + nscoord contentTopOffset = (legendSize.height > border.top) + ? legendSize.height + padding.top + : border.top + padding.top; + ReflowChild(mContentFrame, aPresContext, aDesiredSize, contentReflowState, aStatus); + + contentSize.width = aDesiredSize.width; + contentSize.height = aDesiredSize.height; + + // The content didn't fit + if ((NS_UNCONSTRAINEDSIZE != availSize.width) && (availSize.width < aDesiredSize.width)) { + needAnotherLegendReflow = PR_TRUE; + availSize.width = contentSize.width + borderPadding.left + borderPadding.right; + } + if ((NS_UNCONSTRAINEDSIZE != availSize.height) && (availSize.height < aDesiredSize.height)) { + needAnotherLegendReflow = PR_TRUE; + } + SetMaxElementSize(maxElementSize, aDesiredSize.maxElementSize); + + // need to reflow the legend a 2nd time + if (needAnotherLegendReflow && mLegendFrame) { + nsHTMLReflowState legendReflowState(mLegendFrame, aReflowState, availSize); + ReflowChild(mLegendFrame, aPresContext, aDesiredSize, legendReflowState, aStatus); + + legendSize.width = aDesiredSize.width; + legendSize.height = aDesiredSize.height; + } + + nscoord legendWidth = legendSize.width + border.left + border.right + (2 * minTopBorder); + nscoord contentWidth = contentSize.width + borderPadding.left + borderPadding.right; + + aDesiredSize.width = (legendWidth > contentWidth) ? legendWidth : contentWidth; + + // Place the legend + nsRect legendRect(0, 0, 0, 0); + contentTopOffset = border.top + padding.top; + if (mInline) // XXX parents don't handle inline top, bottom margins + contentTopOffset += margin.top; + if (mLegendFrame) { + nscoord legendTopOffset; + if (legendSize.height > border.top) { + legendTopOffset = (mInline) ? margin.top : 0; // XXX parents don't ....... + } else { + legendTopOffset = (border.top - legendSize.height) / 2; + if (mInline) // XXX parents don't ...... + legendTopOffset += margin.top; + } + contentTopOffset = legendTopOffset + legendSize.height + padding.top; + + nscoord legendLeftOffset = 0; + PRInt32 align = ((nsLegendFrame*)mLegendFrame)->GetAlign(); + + switch(align) { + case NS_STYLE_TEXT_ALIGN_LEFT: + legendLeftOffset = border.left + minTopBorder; + break; + case NS_STYLE_TEXT_ALIGN_RIGHT: + legendLeftOffset = aDesiredSize.width - border.right - minTopBorder - legendSize.width; + break; + // XXX The spec specifies center and top but we are following IE4's lead and making left + // be the upper left and right be the upper right. IE4 introduced center which is not part + // of the spec. + case NS_STYLE_TEXT_ALIGN_CENTER: + case NS_STYLE_VERTICAL_ALIGN_BOTTOM: + case NS_STYLE_VERTICAL_ALIGN_TOP: + default: + legendLeftOffset = (aDesiredSize.width - legendSize.width) / 2; + break; + } + + // reduce by legend margins + legendRect = nsRect(legendLeftOffset + legendMargin.left, legendTopOffset + legendMargin.top, + legendSize.width, legendSize.height); + mLegendFrame->SetRect(legendRect); + + // cache values so the border will be painted around the vertical center of the legend + mTopBorderOffset = legendSize.height / 2; + if (mInline) // XXX parents don't yet ..... + mTopBorderOffset += margin.top; + mTopBorderGap = nsRect(legendLeftOffset, legendTopOffset, legendSize.width + legendMargin.left + + legendMargin.right, legendSize.height + legendMargin.top + + legendMargin.bottom); + } + + // Place the content frame + nsRect contentRect(borderPadding.left, contentTopOffset, contentSize.width, contentSize.height); + mContentFrame->SetRect(contentRect); + + // Return our size and our result + aDesiredSize.height = contentTopOffset + contentSize.height + borderPadding.bottom; + if (mInline) // XXX parents don't yet ...... + aDesiredSize.height += margin.bottom; + aDesiredSize.ascent = aDesiredSize.height; + aDesiredSize.descent = 0; + if (nsnull != aDesiredSize.maxElementSize) { + *aDesiredSize.maxElementSize = maxElementSize; + } + + aStatus = NS_FRAME_COMPLETE; + return NS_OK; +} + +PRIntn +nsFieldSetFrame::GetSkipSides() const +{ + return 0; +} + diff --git a/mozilla/layout/forms/nsFormControlFrame.cpp b/mozilla/layout/forms/nsFormControlFrame.cpp index 240a04cac8d..13ea06969d7 100644 --- a/mozilla/layout/forms/nsFormControlFrame.cpp +++ b/mozilla/layout/forms/nsFormControlFrame.cpp @@ -309,18 +309,25 @@ nsFormControlFrame::GetWidgetInitData(nsIPresContext& aPresContext) } void -nsFormControlFrame::SetColors() +nsFormControlFrame::SetColors(nsIPresContext& aPresContext) { if (mWidget) { - const nsStyleColor* color = nsStyleUtil::FindNonTransparentBackground(mStyleContext); - if (nsnull != color) { - mWidget->SetBackgroundColor(color->mBackgroundColor); - } else { - mWidget->SetBackgroundColor(NS_RGB(0xFF, 0xFF, 0xFF)); - } - const nsStyleColor* myColor = + nsCompatibility mode; + aPresContext.GetCompatibilityMode(mode); + const nsStyleColor* color = (const nsStyleColor*)mStyleContext->GetStyleData(eStyleStruct_Color); - mWidget->SetForegroundColor(myColor->mColor); + if (nsnull != color) { + if (!(NS_STYLE_BG_COLOR_TRANSPARENT & color->mBackgroundFlags)) { + mWidget->SetBackgroundColor(color->mBackgroundColor); +#ifdef bug_1021_closed + } else if (eCompatibility_NavQuirks == mode) { +#else + } else { +#endif + mWidget->SetBackgroundColor(NS_RGB(0xFF, 0xFF, 0xFF)); + } + mWidget->SetForegroundColor(color->mColor); + } } } @@ -564,7 +571,7 @@ void nsFormControlFrame::GetStyleSize(nsIPresContext& aPresContext, } } -void +nsCompatibility GetRepChars(nsIPresContext& aPresContext, char& char1, char& char2) { nsCompatibility mode; @@ -572,9 +579,11 @@ GetRepChars(nsIPresContext& aPresContext, char& char1, char& char2) if (eCompatibility_Standard == mode) { char1 = 'm'; char2 = 'a'; + return eCompatibility_Standard; } else { char1 = '%'; char2 = '%'; + return eCompatibility_NavQuirks; } } @@ -595,7 +604,7 @@ nsFormControlFrame::GetTextSize(nsIPresContext& aPresContext, nsFormControlFrame fontMet->GetHeight(aSize.height); char char1, char2; - GetRepChars(aPresContext, char1, char2); + nsCompatibility mode = GetRepChars(aPresContext, char1, char2); nscoord char1Width, char2Width; aRendContext->GetWidth(char1, char1Width); aRendContext->GetWidth(char2, char2Width); @@ -603,8 +612,12 @@ nsFormControlFrame::GetTextSize(nsIPresContext& aPresContext, nsFormControlFrame NS_RELEASE(fontMet); NS_RELEASE(deviceContext); - return ((char1Width + char2Width) / 2) + 1; -} + if (eCompatibility_Standard == mode) { + return ((char1Width + char2Width) / 2) + 1; + } else { + return char1Width; + } +} nscoord nsFormControlFrame::GetTextSize(nsIPresContext& aPresContext, nsFormControlFrame* aFrame, diff --git a/mozilla/layout/forms/nsFormControlFrame.h b/mozilla/layout/forms/nsFormControlFrame.h index 5506f84ec20..4d70c38f61f 100644 --- a/mozilla/layout/forms/nsFormControlFrame.h +++ b/mozilla/layout/forms/nsFormControlFrame.h @@ -168,7 +168,7 @@ public: * created. */ virtual void PostCreateWidget(nsIPresContext* aPresContext); - void SetColors(); + void SetColors(nsIPresContext& aPresContext); virtual void Reset(); virtual PRBool IsSuccessful(); diff --git a/mozilla/layout/forms/nsLegendFrame.cpp b/mozilla/layout/forms/nsLegendFrame.cpp new file mode 100644 index 00000000000..7cf072ab28d --- /dev/null +++ b/mozilla/layout/forms/nsLegendFrame.cpp @@ -0,0 +1,182 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +// YY need to pass isMultiple before create called + +//#include "nsFormControlFrame.h" +#include "nsLegendFrame.h" +#include "nsIDOMNode.h" +#include "nsIDOMHTMLLegendElement.h" +#include "nsCSSRendering.h" +//#include "nsIDOMHTMLCollection.h" +#include "nsIContent.h" +//#include "prtypes.h" +#include "nsIFrame.h" +#include "nsISupports.h" +#include "nsIAtom.h" +#include "nsIPresContext.h" +#include "nsIHTMLContent.h" +#include "nsHTMLIIDs.h" +#include "nsHTMLParts.h" +//#include "nsIRadioButton.h" +//#include "nsWidgetsCID.h" +//#include "nsSize.h" +#include "nsHTMLAtoms.h" +//#include "nsIView.h" +//#include "nsIListWidget.h" +//#include "nsIComboBox.h" +//#include "nsIListBox.h" +#include "nsIStyleContext.h" +#include "nsStyleConsts.h" +#include "nsStyleUtil.h" +#include "nsFont.h" + +static NS_DEFINE_IID(kLegendFrameCID, NS_LEGEND_FRAME_CID); +static NS_DEFINE_IID(kIDOMHTMLLegendElementIID, NS_IDOMHTMLLEGENDELEMENT_IID); + +nsresult +NS_NewLegendFrame(nsIContent* aContent, + nsIFrame* aParent, + nsIFrame*& aResult) +{ + aResult = new nsLegendFrame(aContent, aParent); + if (nsnull == aResult) { + return NS_ERROR_OUT_OF_MEMORY; + } + return NS_OK; +} + +nsLegendFrame::nsLegendFrame(nsIContent* aContent, + nsIFrame* aParentFrame) + : nsHTMLContainerFrame(aContent, aParentFrame) +{ + mInline = PR_FALSE; +} + +nsLegendFrame::~nsLegendFrame() +{ +} + +NS_IMETHODIMP +nsLegendFrame::QueryInterface(REFNSIID aIID, void** aInstancePtrResult) +{ + NS_PRECONDITION(nsnull != aInstancePtrResult, "null pointer"); + if (nsnull == aInstancePtrResult) { + return NS_ERROR_NULL_POINTER; + } + if (aIID.Equals(kLegendFrameCID)) { + *aInstancePtrResult = (void*) ((nsLegendFrame*)this); + return NS_OK; + } + return nsHTMLContainerFrame::QueryInterface(aIID, aInstancePtrResult); +} + +NS_IMETHODIMP +nsLegendFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList) +{ + // cache our display type + const nsStyleDisplay* styleDisplay; + GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) styleDisplay); + mInline = (NS_STYLE_DISPLAY_BLOCK != styleDisplay->mDisplay); + + if (mInline) { + NS_NewInlineFrame(mContent, this, mFirstChild); + } else { + NS_NewBodyFrame(mContent, this, mFirstChild, PR_FALSE); + } + + // Resolve style and set the style context + nsIStyleContext* styleContext = + aPresContext.ResolveStyleContextFor(mContent, this); + mFirstChild->SetStyleContext(&aPresContext, styleContext); + NS_RELEASE(styleContext); + + // Set the geometric and content parent for each of the child frames + for (nsIFrame* frame = aChildList; nsnull != frame; frame->GetNextSibling(frame)) { + frame->SetGeometricParent(mFirstChild); + frame->SetContentParent(mFirstChild); + } + + // Queue up the frames for the inline frame + return mFirstChild->Init(aPresContext, aChildList); +} + +NS_IMETHODIMP +nsLegendFrame::Paint(nsIPresContext& aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect) +{ + return nsHTMLContainerFrame::Paint(aPresContext, aRenderingContext, aDirtyRect); +} + +NS_IMETHODIMP +nsLegendFrame::Reflow(nsIPresContext& aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus) +{ + nsSize availSize(aReflowState.maxSize); + + // Try to reflow the child into the available space. It might not fit + nsHTMLReflowState reflowState(mFirstChild, aReflowState, availSize); + //nsIHTMLReflow* htmlReflow = nsnull; + //if (NS_OK == mFirstChild->QueryInterface(kIHTMLReflowIID, (void**)&htmlReflow)) { + //htmlReflow->WillReflow(aPresContext); + //mFirstChild->MoveTo(0, 0); + ReflowChild(mFirstChild, aPresContext, aDesiredSize, reflowState, aStatus); + //} + + // Place the child + nsRect rect = nsRect(0, 0, aDesiredSize.width, aDesiredSize.height); + mFirstChild->SetRect(rect); + + aDesiredSize.ascent = aDesiredSize.height; + aDesiredSize.descent = 0; + + aStatus = NS_FRAME_COMPLETE; + return NS_OK; +} + +PRInt32 nsLegendFrame::GetAlign() +{ + PRInt32 intValue = NS_STYLE_TEXT_ALIGN_CENTER; + nsIHTMLContent* content = nsnull; + mContent->QueryInterface(kIHTMLContentIID, (void**) &content); + if (nsnull != content) { + nsHTMLValue value; + if (NS_CONTENT_ATTR_HAS_VALUE == (content->GetAttribute(nsHTMLAtoms::align, value))) { + if (eHTMLUnit_Enumerated == value.GetUnit()) { + intValue = value.GetIntValue(); + } + } + NS_RELEASE(content); + } + return intValue; +} + +PRIntn +nsLegendFrame::GetSkipSides() const +{ + return 0; +} + +PRBool +nsLegendFrame::IsInline() +{ + return mInline; +} diff --git a/mozilla/layout/forms/nsLegendFrame.h b/mozilla/layout/forms/nsLegendFrame.h new file mode 100644 index 00000000000..76eafc851c7 --- /dev/null +++ b/mozilla/layout/forms/nsLegendFrame.h @@ -0,0 +1,68 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef nsLegendFrame_h___ +#define nsLegendFrame_h___ + +#include "nsHTMLContainerFrame.h" +class nsIContent; +class nsIFrame; +class nsIPresContext; +struct nsHTMLReflowMetrics; +class nsIRenderingContext; +struct nsRect; + +#define NS_LEGEND_FRAME_CID \ +{ 0x73805d40, 0x5a24, 0x11d2, { 0x80, 0x46, 0x0, 0x60, 0x8, 0x15, 0xa7, 0x91 } } + +class nsLegendFrame : public nsHTMLContainerFrame { +public: + + nsLegendFrame(nsIContent* aContent, nsIFrame* aParentFrame); + + NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr); + + NS_IMETHOD Init(nsIPresContext& aPresContext, nsIFrame* aChildList); + + NS_IMETHOD Reflow(nsIPresContext& aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus); + + NS_METHOD Paint(nsIPresContext& aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect); + + PRInt32 nsLegendFrame::GetAlign(); + + PRBool IsInline(); + +protected: + + virtual ~nsLegendFrame(); + PRIntn GetSkipSides() const; + PRBool mInline; + + //virtual void GetDesiredSize(nsIPresContext* aPresContext, + // const nsReflowState& aReflowState, + // nsReflowMetrics& aDesiredLayoutSize, + // nsSize& aDesiredWidgetSize); +}; + + +#endif // guard diff --git a/mozilla/layout/forms/nsTextControlFrame.cpp b/mozilla/layout/forms/nsTextControlFrame.cpp index b15762c78c8..250e46bc026 100644 --- a/mozilla/layout/forms/nsTextControlFrame.cpp +++ b/mozilla/layout/forms/nsTextControlFrame.cpp @@ -282,7 +282,7 @@ nsTextControlFrame::PostCreateWidget(nsIPresContext* aPresContext) nsFont font(aPresContext->GetDefaultFixedFont()); GetFont(aPresContext, font); mWidget->SetFont(font); - SetColors(); + SetColors(*aPresContext); PRUint32 ignore; @@ -301,7 +301,6 @@ nsTextControlFrame::PostCreateWidget(nsIPresContext* aPresContext) NS_RELEASE(text); } else if (NS_OK == mWidget->QueryInterface(kITextAreaWidgetIID,(void**)&textArea)) { textArea->SetText(value, ignore); - mWidget->SetBackgroundColor(NS_RGB(0xFF, 0xFF, 0xFF)); NS_RELEASE(textArea); } } diff --git a/mozilla/layout/generic/nsHTMLParts.h b/mozilla/layout/generic/nsHTMLParts.h index aabf8abf7e2..fdcbde9af90 100644 --- a/mozilla/layout/generic/nsHTMLParts.h +++ b/mozilla/layout/generic/nsHTMLParts.h @@ -73,6 +73,9 @@ NS_NewHTMLDivElement(nsIHTMLContent** aResult, nsIAtom* aTag); extern nsresult NS_NewHTMLEmbedElement(nsIHTMLContent** aResult, nsIAtom* aTag); +extern nsresult +NS_NewHTMLFieldSetElement(nsIHTMLContent** aResult, nsIAtom* aTag); + extern nsresult NS_NewHTMLFontElement(nsIHTMLContent** aResult, nsIAtom* aTag); @@ -313,10 +316,18 @@ extern nsresult NS_NewCheckboxControlFrame(nsIContent* aContent, nsIFrame* aParentFrame, nsIFrame*& aResult); +extern nsresult +NS_NewFieldSetFrame(nsIContent* aContent, nsIFrame* aParentFrame, + nsIFrame*& aResult); + extern nsresult NS_NewFileControlFrame(nsIContent* aContent, nsIFrame* aParentFrame, nsIFrame*& aResult); +extern nsresult +NS_NewLegendFrame(nsIContent* aContent, nsIFrame* aParentFrame, + nsIFrame*& aResult); + extern nsresult NS_NewTextControlFrame(nsIContent* aContent, nsIFrame* aParentFrame, nsIFrame*& aResult); diff --git a/mozilla/layout/html/base/src/nsHTMLAtoms.cpp b/mozilla/layout/html/base/src/nsHTMLAtoms.cpp index 616124cef9d..15a5ee9687b 100644 --- a/mozilla/layout/html/base/src/nsHTMLAtoms.cpp +++ b/mozilla/layout/html/base/src/nsHTMLAtoms.cpp @@ -83,6 +83,7 @@ nsIAtom* nsHTMLAtoms::embed; nsIAtom* nsHTMLAtoms::encoding; nsIAtom* nsHTMLAtoms::enctype; nsIAtom* nsHTMLAtoms::face; +nsIAtom* nsHTMLAtoms::fieldset; nsIAtom* nsHTMLAtoms::font; nsIAtom* nsHTMLAtoms::fontWeight; nsIAtom* nsHTMLAtoms::_for; @@ -121,6 +122,7 @@ nsIAtom* nsHTMLAtoms::link; nsIAtom* nsHTMLAtoms::left; nsIAtom* nsHTMLAtoms::leftpadding; nsIAtom* nsHTMLAtoms::length; +nsIAtom* nsHTMLAtoms::legend; nsIAtom* nsHTMLAtoms::longdesc; nsIAtom* nsHTMLAtoms::lowsrc; nsIAtom* nsHTMLAtoms::marginheight; @@ -294,6 +296,7 @@ void nsHTMLAtoms::AddrefAtoms() encoding = NS_NewAtom("ENCODING"); enctype = NS_NewAtom("ENCTYPE"); face = NS_NewAtom("FACE"); + fieldset = NS_NewAtom("FIELDSET"); font = NS_NewAtom("FONT"); fontWeight = NS_NewAtom("FONT-WEIGHT"); _for = NS_NewAtom("FOR"); @@ -331,6 +334,7 @@ void nsHTMLAtoms::AddrefAtoms() link = NS_NewAtom("LINK"); left = NS_NewAtom("LEFT"); leftpadding = NS_NewAtom("LEFTPADDING"); + legend = NS_NewAtom("LEGEND"); length = NS_NewAtom("LENGTH"); lowsrc = NS_NewAtom("LOWSRC"); marginheight = NS_NewAtom("MARGINHEIGHT"); @@ -501,6 +505,7 @@ void nsHTMLAtoms::ReleaseAtoms() NS_RELEASE(embed); NS_RELEASE(encoding); NS_RELEASE(face); + NS_RELEASE(fieldset); NS_RELEASE(font); NS_RELEASE(fontWeight); NS_RELEASE(_for); @@ -535,6 +540,7 @@ void nsHTMLAtoms::ReleaseAtoms() NS_RELEASE(link); NS_RELEASE(left); NS_RELEASE(leftpadding); + NS_RELEASE(legend); NS_RELEASE(length); NS_RELEASE(lowsrc); NS_RELEASE(marginheight); diff --git a/mozilla/layout/html/base/src/nsHTMLAtoms.h b/mozilla/layout/html/base/src/nsHTMLAtoms.h index b5c635c3d88..c65e06d5233 100644 --- a/mozilla/layout/html/base/src/nsHTMLAtoms.h +++ b/mozilla/layout/html/base/src/nsHTMLAtoms.h @@ -107,6 +107,7 @@ public: static nsIAtom* enctype; static nsIAtom* face; + static nsIAtom* fieldset; static nsIAtom* font; static nsIAtom* fontWeight; static nsIAtom* _for; @@ -148,6 +149,7 @@ public: static nsIAtom* link; static nsIAtom* left; static nsIAtom* leftpadding; + static nsIAtom* legend; static nsIAtom* length; static nsIAtom* longdesc; static nsIAtom* lowsrc; diff --git a/mozilla/layout/html/base/src/nsHTMLParts.h b/mozilla/layout/html/base/src/nsHTMLParts.h index aabf8abf7e2..fdcbde9af90 100644 --- a/mozilla/layout/html/base/src/nsHTMLParts.h +++ b/mozilla/layout/html/base/src/nsHTMLParts.h @@ -73,6 +73,9 @@ NS_NewHTMLDivElement(nsIHTMLContent** aResult, nsIAtom* aTag); extern nsresult NS_NewHTMLEmbedElement(nsIHTMLContent** aResult, nsIAtom* aTag); +extern nsresult +NS_NewHTMLFieldSetElement(nsIHTMLContent** aResult, nsIAtom* aTag); + extern nsresult NS_NewHTMLFontElement(nsIHTMLContent** aResult, nsIAtom* aTag); @@ -313,10 +316,18 @@ extern nsresult NS_NewCheckboxControlFrame(nsIContent* aContent, nsIFrame* aParentFrame, nsIFrame*& aResult); +extern nsresult +NS_NewFieldSetFrame(nsIContent* aContent, nsIFrame* aParentFrame, + nsIFrame*& aResult); + extern nsresult NS_NewFileControlFrame(nsIContent* aContent, nsIFrame* aParentFrame, nsIFrame*& aResult); +extern nsresult +NS_NewLegendFrame(nsIContent* aContent, nsIFrame* aParentFrame, + nsIFrame*& aResult); + extern nsresult NS_NewTextControlFrame(nsIContent* aContent, nsIFrame* aParentFrame, nsIFrame*& aResult); diff --git a/mozilla/layout/html/content/src/nsHTMLFieldSetElement.cpp b/mozilla/layout/html/content/src/nsHTMLFieldSetElement.cpp index b52b1aa4967..4961456550f 100644 --- a/mozilla/layout/html/content/src/nsHTMLFieldSetElement.cpp +++ b/mozilla/layout/html/content/src/nsHTMLFieldSetElement.cpp @@ -180,16 +180,28 @@ nsHTMLFieldSetElement::GetForm(nsIDOMHTMLFormElement** aForm) return result; } +// An important assumption is that if aForm is null, the previous mForm will not be released +// This allows nsHTMLFormElement to deal with circular references. NS_IMETHODIMP nsHTMLFieldSetElement::SetForm(nsIDOMHTMLFormElement* aForm) { + nsresult result = NS_OK; if (nsnull == aForm) { mForm = nsnull; return NS_OK; } else { NS_IF_RELEASE(mForm); - return aForm->QueryInterface(kIFormIID, (void**)&mForm); + nsIFormControl* formControl = nsnull; + result = QueryInterface(kIFormControlIID, (void**)&formControl); + if ((NS_OK == result) && formControl) { + result = aForm->QueryInterface(kIFormIID, (void**)&mForm); // keep the ref + if ((NS_OK == result) && mForm) { + mForm->AddElement(formControl); + } + NS_RELEASE(formControl); + } } + return result; } NS_IMETHODIMP diff --git a/mozilla/layout/html/document/src/nsHTMLContentSink.cpp b/mozilla/layout/html/document/src/nsHTMLContentSink.cpp index fcc63bc5532..fd57765d43b 100644 --- a/mozilla/layout/html/document/src/nsHTMLContentSink.cpp +++ b/mozilla/layout/html/document/src/nsHTMLContentSink.cpp @@ -522,6 +522,10 @@ MakeContentObject(nsHTMLTag aNodeType, case eHTMLTag_embed: rv = NS_NewHTMLEmbedElement(aResult, aAtom); break; + case eHTMLTag_fieldset: + rv = NS_NewHTMLFieldSetElement(aResult, aAtom); + SetForm(*aResult, aForm); + break; case eHTMLTag_font: rv = NS_NewHTMLFontElement(aResult, aAtom); break; diff --git a/mozilla/layout/html/document/src/ua.css b/mozilla/layout/html/document/src/ua.css index ff0aabc32c8..cbbcb367fd8 100644 --- a/mozilla/layout/html/document/src/ua.css +++ b/mozilla/layout/html/document/src/ua.css @@ -291,11 +291,17 @@ NOBR { white-space: nowrap; } LEGEND { - display: none; + display: block; + padding-left: 2px; + padding-right: 2px; + border: 2px solid black; } FIELDSET { - display: inline; - border: inset 2px white; + display: block; + border: 2px solid black; + padding: 4px; + margin-left: 2px; + margin-right: 2px; } // Lists diff --git a/mozilla/layout/html/forms/src/Makefile b/mozilla/layout/html/forms/src/Makefile index 43c2803e6cb..6e2e038ad5e 100644 --- a/mozilla/layout/html/forms/src/Makefile +++ b/mozilla/layout/html/forms/src/Makefile @@ -33,6 +33,8 @@ CPPSRCS = \ nsRadioControlFrame.cpp \ nsTextControlFrame.cpp \ nsSelectControlFrame.cpp \ + nsFieldSetFrame.cpp \ + nsLegendFrame.cpp \ $(NULL) MODULE = raptor diff --git a/mozilla/layout/html/forms/src/makefile.win b/mozilla/layout/html/forms/src/makefile.win index 5d278fe612e..ed65a4c178d 100644 --- a/mozilla/layout/html/forms/src/makefile.win +++ b/mozilla/layout/html/forms/src/makefile.win @@ -24,12 +24,14 @@ MODULE=raptor REQUIRES=xpcom raptor js CPPSRCS=nsFormFrame.cpp nsFormControlFrame.cpp nsButtonControlFrame.cpp nsCheckboxControlFrame.cpp \ - nsFileControlFrame.cpp nsRadioControlFrame.cpp nsTextControlFrame.cpp nsSelectControlFrame.cpp + nsFileControlFrame.cpp nsRadioControlFrame.cpp nsTextControlFrame.cpp nsSelectControlFrame.cpp \ + nsFieldSetFrame.cpp nsLegendFrame.cpp CPP_OBJS=.\$(OBJDIR)\nsFormFrame.obj .\$(OBJDIR)\nsFormControlFrame.obj \ .\$(OBJDIR)\nsButtonControlFrame.obj .\$(OBJDIR)\nsCheckboxControlFrame.obj \ .\$(OBJDIR)\nsFileControlFrame.obj .\$(OBJDIR)\nsRadioControlFrame.obj \ - .\$(OBJDIR)\nsTextControlFrame.obj .\$(OBJDIR)\nsSelectControlFrame.obj + .\$(OBJDIR)\nsTextControlFrame.obj .\$(OBJDIR)\nsSelectControlFrame.obj \ + .\$(OBJDIR)\nsFieldSetFrame.obj .\$(OBJDIR)\nsLegendFrame.obj LINCS=-I$(PUBLIC)\xpcom -I$(PUBLIC)\raptor -I$(PUBLIC)\js \ -I$(PUBLIC)\dom -I$(PUBLIC)\netlib \ diff --git a/mozilla/layout/html/forms/src/nsButtonControlFrame.cpp b/mozilla/layout/html/forms/src/nsButtonControlFrame.cpp index a6d4c975fb7..be0b1a80566 100644 --- a/mozilla/layout/html/forms/src/nsButtonControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsButtonControlFrame.cpp @@ -359,7 +359,7 @@ nsButtonControlFrame::PostCreateWidget(nsIPresContext* aPresContext) nsFont font(aPresContext->GetDefaultFixedFont()); GetFont(aPresContext, font); mWidget->SetFont(font); - SetColors(); + SetColors(*aPresContext); nsString value; nsresult result = GetValue(&value); diff --git a/mozilla/layout/html/forms/src/nsCheckboxControlFrame.cpp b/mozilla/layout/html/forms/src/nsCheckboxControlFrame.cpp index 6f958ddbbce..8d4a8d17416 100644 --- a/mozilla/layout/html/forms/src/nsCheckboxControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsCheckboxControlFrame.cpp @@ -151,7 +151,7 @@ nsCheckboxControlFrame::PostCreateWidget(nsIPresContext* aPresContext) if (mWidget && (NS_OK == mWidget->QueryInterface(GetIID(),(void**)&checkbox))) { checkbox->SetState(checked); - SetColors(); + SetColors(*aPresContext); NS_IF_RELEASE(checkbox); } } diff --git a/mozilla/layout/html/forms/src/nsFieldSetFrame.cpp b/mozilla/layout/html/forms/src/nsFieldSetFrame.cpp new file mode 100644 index 00000000000..13c83339092 --- /dev/null +++ b/mozilla/layout/html/forms/src/nsFieldSetFrame.cpp @@ -0,0 +1,420 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +// YY need to pass isMultiple before create called + +//#include "nsFormControlFrame.h" +#include "nsHTMLContainerFrame.h" +#include "nsLegendFrame.h" +#include "nsIDOMNode.h" +#include "nsIDOMHTMLFieldSetElement.h" +#include "nsIDOMHTMLLegendElement.h" +#include "nsCSSRendering.h" +//#include "nsIDOMHTMLCollection.h" +#include "nsIContent.h" +//#include "prtypes.h" +#include "nsIFrame.h" +#include "nsISupports.h" +#include "nsIAtom.h" +#include "nsIPresContext.h" +#include "nsIHTMLContent.h" +#include "nsHTMLIIDs.h" +#include "nsHTMLParts.h" +//#include "nsIRadioButton.h" +//#include "nsWidgetsCID.h" +//#include "nsSize.h" +//#include "nsHTMLAtoms.h" +//#include "nsIView.h" +//#include "nsIListWidget.h" +//#include "nsIComboBox.h" +//#include "nsIListBox.h" +#include "nsIStyleContext.h" +#include "nsStyleConsts.h" +#include "nsStyleUtil.h" +#include "nsFont.h" + +static NS_DEFINE_IID(kLegendFrameCID, NS_LEGEND_FRAME_CID); +static NS_DEFINE_IID(kIDOMHTMLFieldSetElementIID, NS_IDOMHTMLFIELDSETELEMENT_IID); +static NS_DEFINE_IID(kIDOMHTMLLegendElementIID, NS_IDOMHTMLLEGENDELEMENT_IID); + +class nsLegendFrame; + +class nsFieldSetFrame : public nsHTMLContainerFrame { +public: + + nsFieldSetFrame(nsIContent* aContent, nsIFrame* aParentFrame); + + NS_IMETHOD Init(nsIPresContext& aPresContext, nsIFrame* aChildList); + + NS_IMETHOD Reflow(nsIPresContext& aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus); + + NS_METHOD Paint(nsIPresContext& aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect); +protected: + + virtual ~nsFieldSetFrame(); + + void nsFieldSetFrame::SetMaxElementSize(nsSize& maxSize, nsSize* aSize); + virtual PRIntn GetSkipSides() const; + //virtual void GetDesiredSize(nsIPresContext* aPresContext, + // const nsReflowState& aReflowState, + // nsReflowMetrics& aDesiredLayoutSize, + // nsSize& aDesiredWidgetSize); + + nsIFrame* mLegendFrame; + nsIFrame* mContentFrame; + nsRect mTopBorderGap; + PRInt32 mTopBorderOffset; + PRBool mInline; +}; + +nsresult +NS_NewFieldSetFrame(nsIContent* aContent, + nsIFrame* aParent, + nsIFrame*& aResult) +{ + aResult = new nsFieldSetFrame(aContent, aParent); + if (nsnull == aResult) { + return NS_ERROR_OUT_OF_MEMORY; + } + return NS_OK; +} + +nsFieldSetFrame::nsFieldSetFrame(nsIContent* aContent, + nsIFrame* aParentFrame) + : nsHTMLContainerFrame(aContent, aParentFrame) +{ + mContentFrame = nsnull; + mLegendFrame = nsnull; + mTopBorderGap = nsRect(0,0,0,0); + mTopBorderOffset = 0; + mInline = PR_TRUE; +} + +nsFieldSetFrame::~nsFieldSetFrame() +{ +} + +NS_IMETHODIMP +nsFieldSetFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList) +{ + // cache our display type + const nsStyleDisplay* styleDisplay; + GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) styleDisplay); + mInline = (NS_STYLE_DISPLAY_BLOCK != styleDisplay->mDisplay); + + if (mInline) { + NS_NewInlineFrame(mContent, this, mFirstChild); + } else { + NS_NewBodyFrame(mContent, this, mFirstChild, PR_FALSE); + } + mContentFrame = mFirstChild; + + // Resolve style and set the style context + nsIStyleContext* styleContext = aPresContext.ResolveStyleContextFor(mContent, this); + mFirstChild->SetStyleContext(&aPresContext, styleContext); + NS_RELEASE(styleContext); + + nsIFrame* newChildList = aChildList; + + mFirstChild->SetNextSibling(nsnull); + // Set the geometric and content parent for each of the child frames. + // The legend is handled differently and removed from aChildList + nsIFrame* lastFrame = nsnull; + for (nsIFrame* frame = aChildList; nsnull != frame; frame->GetNextSibling(frame)) { + nsIFrame* legendFrame = nsnull; + nsresult result = frame->QueryInterface(kLegendFrameCID, (void**)&legendFrame); + if ((NS_OK == result) && legendFrame) { + nsIFrame* nextFrame; + frame->GetNextSibling(nextFrame); + if (lastFrame) { + lastFrame->SetNextSibling(nextFrame); + } else { + newChildList = nextFrame; + } + frame->SetGeometricParent(this); + frame->SetContentParent(this); + mFirstChild->SetNextSibling(frame); + mLegendFrame = frame; + mLegendFrame->SetNextSibling(nsnull); + } else { + frame->SetGeometricParent(mFirstChild); + frame->SetContentParent(mFirstChild); + } + lastFrame = frame; + } + + // Queue up the frames for the content frame + return mFirstChild->Init(aPresContext, newChildList); +} + +// this is identical to nsHTMLContainerFrame::Paint except for the background and border. +NS_IMETHODIMP +nsFieldSetFrame::Paint(nsIPresContext& aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect) +{ + // Paint our background and border + const nsStyleDisplay* disp = + (const nsStyleDisplay*)mStyleContext->GetStyleData(eStyleStruct_Display); + + if (disp->mVisible && mRect.width && mRect.height) { + PRIntn skipSides = GetSkipSides(); + const nsStyleColor* color = + (const nsStyleColor*)mStyleContext->GetStyleData(eStyleStruct_Color); + const nsStyleSpacing* spacing = + (const nsStyleSpacing*)mStyleContext->GetStyleData(eStyleStruct_Spacing); + + nsRect backgroundRect(0, 0, mRect.width, mRect.height); + // XXX our parent doesn't account for top and bottom margins yet, if we are inline + if (mInline) { + nsMargin margin; + spacing->CalcMarginFor(this, margin); + nsRect rect(0, mTopBorderOffset, mRect.width, mRect.height - margin.top - + margin.bottom - mTopBorderOffset); + nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this, + aDirtyRect, rect, *color, 0, 0); + nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this, + aDirtyRect, rect, *spacing, skipSides, &mTopBorderGap); + } else { + nsRect rect(0, mTopBorderOffset, mRect.width, mRect.height - mTopBorderOffset); + nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this, + aDirtyRect, rect, *color, 0, 0); + nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this, + aDirtyRect, rect, *spacing, skipSides, &mTopBorderGap); + } + } + + PaintChildren(aPresContext, aRenderingContext, aDirtyRect); + + if (nsIFrame::GetShowFrameBorders()) { + nsIView* view; + GetView(view); + if (nsnull != view) { + aRenderingContext.SetColor(NS_RGB(0,0,255)); + } + else { + aRenderingContext.SetColor(NS_RGB(255,0,0)); + } + aRenderingContext.DrawRect(0, 0, mRect.width, mRect.height); + } + return NS_OK; +} + +void +nsFieldSetFrame::SetMaxElementSize(nsSize& maxSize, nsSize* aSize) +{ + if (aSize) { + maxSize.width = (maxSize.width >= aSize->width) ? maxSize.width : aSize->width; + maxSize.height = (maxSize.height >= aSize->width) ? maxSize.height : aSize->height; + } +} + +// XXX currently only supports legend align=left,center,right +#define MIN_TOP_BORDER 10 +NS_IMETHODIMP +nsFieldSetFrame::Reflow(nsIPresContext& aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus) +{ + nsSize availSize(aReflowState.maxSize); + float p2t = aPresContext.GetPixelsToTwips(); + const PRInt32 minTopBorder = NSIntPixelsToTwips(MIN_TOP_BORDER, p2t); + + const nsStyleSpacing* spacing = + (const nsStyleSpacing*)mStyleContext->GetStyleData(eStyleStruct_Spacing); + + nsMargin margin; + spacing->CalcMarginFor(this, margin); + + nsMargin border; + nsMargin padding; + spacing->CalcBorderFor(this, border); + spacing->CalcPaddingFor(this, padding); + nsMargin borderPadding = border + padding; + + nsMargin legendMargin; + if (mLegendFrame) { + nsIStyleContext* legendSC = nsnull; + mLegendFrame->GetStyleContext(&aPresContext, legendSC); + if (legendSC) { + const nsStyleSpacing* legendSpacing = + (const nsStyleSpacing*)legendSC->GetStyleData(eStyleStruct_Spacing); + legendSpacing->CalcMarginFor(mLegendFrame, legendMargin); + NS_RELEASE(legendSC); + } + } + + // reduce available space by border, padding, etc. if we're in a constrained situation + nscoord horTaken = borderPadding.left + borderPadding.right + (2 * minTopBorder) + + legendMargin.left + legendMargin.right; + nscoord verTaken = padding.top + borderPadding.bottom + legendMargin.top + legendMargin.bottom; + if (NS_UNCONSTRAINEDSIZE != availSize.width) + availSize.width -= horTaken; + if (NS_UNCONSTRAINEDSIZE != availSize.height) { + // XXX this assumes that the legend is taller than the top border width + availSize.height -= verTaken; + if (mInline) { // XXX parents don't account for inline top, bottom margins yet + availSize.height -= margin.top; + } + } + if (availSize.height < 0) + availSize.height = 1; + + nsSize maxElementSize(0,0); + nsIHTMLReflow* htmlReflow = nsnull; + + // Try to reflow the legend into the available space. It might not fit + nsSize legendSize(0,0); + if (mLegendFrame) { + nsHTMLReflowState legendReflowState(mLegendFrame, aReflowState, availSize); + ReflowChild(mLegendFrame, aPresContext, aDesiredSize, legendReflowState, aStatus); + + legendSize.width = aDesiredSize.width; + legendSize.height = aDesiredSize.height; + + // The legend didn't fit + if ((NS_UNCONSTRAINEDSIZE != availSize.width) && + (availSize.width < aDesiredSize.width + legendMargin.left + legendMargin.right)) { + availSize.width = aDesiredSize.width + horTaken; + } + if ((NS_UNCONSTRAINEDSIZE != availSize.height) && (availSize.height < aDesiredSize.height)) { + availSize.height = 0; + } else { + availSize.height -= aDesiredSize.height; + } + SetMaxElementSize(maxElementSize, aDesiredSize.maxElementSize); + } + + PRBool needAnotherLegendReflow = PR_FALSE; + + // Try to reflow the content frame into the available space. It might not fit + nsSize contentSize(0,0); + nsHTMLReflowState contentReflowState(mContentFrame, aReflowState, availSize); + nscoord contentTopOffset = (legendSize.height > border.top) + ? legendSize.height + padding.top + : border.top + padding.top; + ReflowChild(mContentFrame, aPresContext, aDesiredSize, contentReflowState, aStatus); + + contentSize.width = aDesiredSize.width; + contentSize.height = aDesiredSize.height; + + // The content didn't fit + if ((NS_UNCONSTRAINEDSIZE != availSize.width) && (availSize.width < aDesiredSize.width)) { + needAnotherLegendReflow = PR_TRUE; + availSize.width = contentSize.width + borderPadding.left + borderPadding.right; + } + if ((NS_UNCONSTRAINEDSIZE != availSize.height) && (availSize.height < aDesiredSize.height)) { + needAnotherLegendReflow = PR_TRUE; + } + SetMaxElementSize(maxElementSize, aDesiredSize.maxElementSize); + + // need to reflow the legend a 2nd time + if (needAnotherLegendReflow && mLegendFrame) { + nsHTMLReflowState legendReflowState(mLegendFrame, aReflowState, availSize); + ReflowChild(mLegendFrame, aPresContext, aDesiredSize, legendReflowState, aStatus); + + legendSize.width = aDesiredSize.width; + legendSize.height = aDesiredSize.height; + } + + nscoord legendWidth = legendSize.width + border.left + border.right + (2 * minTopBorder); + nscoord contentWidth = contentSize.width + borderPadding.left + borderPadding.right; + + aDesiredSize.width = (legendWidth > contentWidth) ? legendWidth : contentWidth; + + // Place the legend + nsRect legendRect(0, 0, 0, 0); + contentTopOffset = border.top + padding.top; + if (mInline) // XXX parents don't handle inline top, bottom margins + contentTopOffset += margin.top; + if (mLegendFrame) { + nscoord legendTopOffset; + if (legendSize.height > border.top) { + legendTopOffset = (mInline) ? margin.top : 0; // XXX parents don't ....... + } else { + legendTopOffset = (border.top - legendSize.height) / 2; + if (mInline) // XXX parents don't ...... + legendTopOffset += margin.top; + } + contentTopOffset = legendTopOffset + legendSize.height + padding.top; + + nscoord legendLeftOffset = 0; + PRInt32 align = ((nsLegendFrame*)mLegendFrame)->GetAlign(); + + switch(align) { + case NS_STYLE_TEXT_ALIGN_LEFT: + legendLeftOffset = border.left + minTopBorder; + break; + case NS_STYLE_TEXT_ALIGN_RIGHT: + legendLeftOffset = aDesiredSize.width - border.right - minTopBorder - legendSize.width; + break; + // XXX The spec specifies center and top but we are following IE4's lead and making left + // be the upper left and right be the upper right. IE4 introduced center which is not part + // of the spec. + case NS_STYLE_TEXT_ALIGN_CENTER: + case NS_STYLE_VERTICAL_ALIGN_BOTTOM: + case NS_STYLE_VERTICAL_ALIGN_TOP: + default: + legendLeftOffset = (aDesiredSize.width - legendSize.width) / 2; + break; + } + + // reduce by legend margins + legendRect = nsRect(legendLeftOffset + legendMargin.left, legendTopOffset + legendMargin.top, + legendSize.width, legendSize.height); + mLegendFrame->SetRect(legendRect); + + // cache values so the border will be painted around the vertical center of the legend + mTopBorderOffset = legendSize.height / 2; + if (mInline) // XXX parents don't yet ..... + mTopBorderOffset += margin.top; + mTopBorderGap = nsRect(legendLeftOffset, legendTopOffset, legendSize.width + legendMargin.left + + legendMargin.right, legendSize.height + legendMargin.top + + legendMargin.bottom); + } + + // Place the content frame + nsRect contentRect(borderPadding.left, contentTopOffset, contentSize.width, contentSize.height); + mContentFrame->SetRect(contentRect); + + // Return our size and our result + aDesiredSize.height = contentTopOffset + contentSize.height + borderPadding.bottom; + if (mInline) // XXX parents don't yet ...... + aDesiredSize.height += margin.bottom; + aDesiredSize.ascent = aDesiredSize.height; + aDesiredSize.descent = 0; + if (nsnull != aDesiredSize.maxElementSize) { + *aDesiredSize.maxElementSize = maxElementSize; + } + + aStatus = NS_FRAME_COMPLETE; + return NS_OK; +} + +PRIntn +nsFieldSetFrame::GetSkipSides() const +{ + return 0; +} + diff --git a/mozilla/layout/html/forms/src/nsFormControlFrame.cpp b/mozilla/layout/html/forms/src/nsFormControlFrame.cpp index 240a04cac8d..13ea06969d7 100644 --- a/mozilla/layout/html/forms/src/nsFormControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsFormControlFrame.cpp @@ -309,18 +309,25 @@ nsFormControlFrame::GetWidgetInitData(nsIPresContext& aPresContext) } void -nsFormControlFrame::SetColors() +nsFormControlFrame::SetColors(nsIPresContext& aPresContext) { if (mWidget) { - const nsStyleColor* color = nsStyleUtil::FindNonTransparentBackground(mStyleContext); - if (nsnull != color) { - mWidget->SetBackgroundColor(color->mBackgroundColor); - } else { - mWidget->SetBackgroundColor(NS_RGB(0xFF, 0xFF, 0xFF)); - } - const nsStyleColor* myColor = + nsCompatibility mode; + aPresContext.GetCompatibilityMode(mode); + const nsStyleColor* color = (const nsStyleColor*)mStyleContext->GetStyleData(eStyleStruct_Color); - mWidget->SetForegroundColor(myColor->mColor); + if (nsnull != color) { + if (!(NS_STYLE_BG_COLOR_TRANSPARENT & color->mBackgroundFlags)) { + mWidget->SetBackgroundColor(color->mBackgroundColor); +#ifdef bug_1021_closed + } else if (eCompatibility_NavQuirks == mode) { +#else + } else { +#endif + mWidget->SetBackgroundColor(NS_RGB(0xFF, 0xFF, 0xFF)); + } + mWidget->SetForegroundColor(color->mColor); + } } } @@ -564,7 +571,7 @@ void nsFormControlFrame::GetStyleSize(nsIPresContext& aPresContext, } } -void +nsCompatibility GetRepChars(nsIPresContext& aPresContext, char& char1, char& char2) { nsCompatibility mode; @@ -572,9 +579,11 @@ GetRepChars(nsIPresContext& aPresContext, char& char1, char& char2) if (eCompatibility_Standard == mode) { char1 = 'm'; char2 = 'a'; + return eCompatibility_Standard; } else { char1 = '%'; char2 = '%'; + return eCompatibility_NavQuirks; } } @@ -595,7 +604,7 @@ nsFormControlFrame::GetTextSize(nsIPresContext& aPresContext, nsFormControlFrame fontMet->GetHeight(aSize.height); char char1, char2; - GetRepChars(aPresContext, char1, char2); + nsCompatibility mode = GetRepChars(aPresContext, char1, char2); nscoord char1Width, char2Width; aRendContext->GetWidth(char1, char1Width); aRendContext->GetWidth(char2, char2Width); @@ -603,8 +612,12 @@ nsFormControlFrame::GetTextSize(nsIPresContext& aPresContext, nsFormControlFrame NS_RELEASE(fontMet); NS_RELEASE(deviceContext); - return ((char1Width + char2Width) / 2) + 1; -} + if (eCompatibility_Standard == mode) { + return ((char1Width + char2Width) / 2) + 1; + } else { + return char1Width; + } +} nscoord nsFormControlFrame::GetTextSize(nsIPresContext& aPresContext, nsFormControlFrame* aFrame, diff --git a/mozilla/layout/html/forms/src/nsFormControlFrame.h b/mozilla/layout/html/forms/src/nsFormControlFrame.h index 5506f84ec20..4d70c38f61f 100644 --- a/mozilla/layout/html/forms/src/nsFormControlFrame.h +++ b/mozilla/layout/html/forms/src/nsFormControlFrame.h @@ -168,7 +168,7 @@ public: * created. */ virtual void PostCreateWidget(nsIPresContext* aPresContext); - void SetColors(); + void SetColors(nsIPresContext& aPresContext); virtual void Reset(); virtual PRBool IsSuccessful(); diff --git a/mozilla/layout/html/forms/src/nsLegendFrame.cpp b/mozilla/layout/html/forms/src/nsLegendFrame.cpp new file mode 100644 index 00000000000..7cf072ab28d --- /dev/null +++ b/mozilla/layout/html/forms/src/nsLegendFrame.cpp @@ -0,0 +1,182 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +// YY need to pass isMultiple before create called + +//#include "nsFormControlFrame.h" +#include "nsLegendFrame.h" +#include "nsIDOMNode.h" +#include "nsIDOMHTMLLegendElement.h" +#include "nsCSSRendering.h" +//#include "nsIDOMHTMLCollection.h" +#include "nsIContent.h" +//#include "prtypes.h" +#include "nsIFrame.h" +#include "nsISupports.h" +#include "nsIAtom.h" +#include "nsIPresContext.h" +#include "nsIHTMLContent.h" +#include "nsHTMLIIDs.h" +#include "nsHTMLParts.h" +//#include "nsIRadioButton.h" +//#include "nsWidgetsCID.h" +//#include "nsSize.h" +#include "nsHTMLAtoms.h" +//#include "nsIView.h" +//#include "nsIListWidget.h" +//#include "nsIComboBox.h" +//#include "nsIListBox.h" +#include "nsIStyleContext.h" +#include "nsStyleConsts.h" +#include "nsStyleUtil.h" +#include "nsFont.h" + +static NS_DEFINE_IID(kLegendFrameCID, NS_LEGEND_FRAME_CID); +static NS_DEFINE_IID(kIDOMHTMLLegendElementIID, NS_IDOMHTMLLEGENDELEMENT_IID); + +nsresult +NS_NewLegendFrame(nsIContent* aContent, + nsIFrame* aParent, + nsIFrame*& aResult) +{ + aResult = new nsLegendFrame(aContent, aParent); + if (nsnull == aResult) { + return NS_ERROR_OUT_OF_MEMORY; + } + return NS_OK; +} + +nsLegendFrame::nsLegendFrame(nsIContent* aContent, + nsIFrame* aParentFrame) + : nsHTMLContainerFrame(aContent, aParentFrame) +{ + mInline = PR_FALSE; +} + +nsLegendFrame::~nsLegendFrame() +{ +} + +NS_IMETHODIMP +nsLegendFrame::QueryInterface(REFNSIID aIID, void** aInstancePtrResult) +{ + NS_PRECONDITION(nsnull != aInstancePtrResult, "null pointer"); + if (nsnull == aInstancePtrResult) { + return NS_ERROR_NULL_POINTER; + } + if (aIID.Equals(kLegendFrameCID)) { + *aInstancePtrResult = (void*) ((nsLegendFrame*)this); + return NS_OK; + } + return nsHTMLContainerFrame::QueryInterface(aIID, aInstancePtrResult); +} + +NS_IMETHODIMP +nsLegendFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList) +{ + // cache our display type + const nsStyleDisplay* styleDisplay; + GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) styleDisplay); + mInline = (NS_STYLE_DISPLAY_BLOCK != styleDisplay->mDisplay); + + if (mInline) { + NS_NewInlineFrame(mContent, this, mFirstChild); + } else { + NS_NewBodyFrame(mContent, this, mFirstChild, PR_FALSE); + } + + // Resolve style and set the style context + nsIStyleContext* styleContext = + aPresContext.ResolveStyleContextFor(mContent, this); + mFirstChild->SetStyleContext(&aPresContext, styleContext); + NS_RELEASE(styleContext); + + // Set the geometric and content parent for each of the child frames + for (nsIFrame* frame = aChildList; nsnull != frame; frame->GetNextSibling(frame)) { + frame->SetGeometricParent(mFirstChild); + frame->SetContentParent(mFirstChild); + } + + // Queue up the frames for the inline frame + return mFirstChild->Init(aPresContext, aChildList); +} + +NS_IMETHODIMP +nsLegendFrame::Paint(nsIPresContext& aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect) +{ + return nsHTMLContainerFrame::Paint(aPresContext, aRenderingContext, aDirtyRect); +} + +NS_IMETHODIMP +nsLegendFrame::Reflow(nsIPresContext& aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus) +{ + nsSize availSize(aReflowState.maxSize); + + // Try to reflow the child into the available space. It might not fit + nsHTMLReflowState reflowState(mFirstChild, aReflowState, availSize); + //nsIHTMLReflow* htmlReflow = nsnull; + //if (NS_OK == mFirstChild->QueryInterface(kIHTMLReflowIID, (void**)&htmlReflow)) { + //htmlReflow->WillReflow(aPresContext); + //mFirstChild->MoveTo(0, 0); + ReflowChild(mFirstChild, aPresContext, aDesiredSize, reflowState, aStatus); + //} + + // Place the child + nsRect rect = nsRect(0, 0, aDesiredSize.width, aDesiredSize.height); + mFirstChild->SetRect(rect); + + aDesiredSize.ascent = aDesiredSize.height; + aDesiredSize.descent = 0; + + aStatus = NS_FRAME_COMPLETE; + return NS_OK; +} + +PRInt32 nsLegendFrame::GetAlign() +{ + PRInt32 intValue = NS_STYLE_TEXT_ALIGN_CENTER; + nsIHTMLContent* content = nsnull; + mContent->QueryInterface(kIHTMLContentIID, (void**) &content); + if (nsnull != content) { + nsHTMLValue value; + if (NS_CONTENT_ATTR_HAS_VALUE == (content->GetAttribute(nsHTMLAtoms::align, value))) { + if (eHTMLUnit_Enumerated == value.GetUnit()) { + intValue = value.GetIntValue(); + } + } + NS_RELEASE(content); + } + return intValue; +} + +PRIntn +nsLegendFrame::GetSkipSides() const +{ + return 0; +} + +PRBool +nsLegendFrame::IsInline() +{ + return mInline; +} diff --git a/mozilla/layout/html/forms/src/nsLegendFrame.h b/mozilla/layout/html/forms/src/nsLegendFrame.h new file mode 100644 index 00000000000..76eafc851c7 --- /dev/null +++ b/mozilla/layout/html/forms/src/nsLegendFrame.h @@ -0,0 +1,68 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef nsLegendFrame_h___ +#define nsLegendFrame_h___ + +#include "nsHTMLContainerFrame.h" +class nsIContent; +class nsIFrame; +class nsIPresContext; +struct nsHTMLReflowMetrics; +class nsIRenderingContext; +struct nsRect; + +#define NS_LEGEND_FRAME_CID \ +{ 0x73805d40, 0x5a24, 0x11d2, { 0x80, 0x46, 0x0, 0x60, 0x8, 0x15, 0xa7, 0x91 } } + +class nsLegendFrame : public nsHTMLContainerFrame { +public: + + nsLegendFrame(nsIContent* aContent, nsIFrame* aParentFrame); + + NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr); + + NS_IMETHOD Init(nsIPresContext& aPresContext, nsIFrame* aChildList); + + NS_IMETHOD Reflow(nsIPresContext& aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus); + + NS_METHOD Paint(nsIPresContext& aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect); + + PRInt32 nsLegendFrame::GetAlign(); + + PRBool IsInline(); + +protected: + + virtual ~nsLegendFrame(); + PRIntn GetSkipSides() const; + PRBool mInline; + + //virtual void GetDesiredSize(nsIPresContext* aPresContext, + // const nsReflowState& aReflowState, + // nsReflowMetrics& aDesiredLayoutSize, + // nsSize& aDesiredWidgetSize); +}; + + +#endif // guard diff --git a/mozilla/layout/html/forms/src/nsSelectControlFrame.cpp b/mozilla/layout/html/forms/src/nsSelectControlFrame.cpp index e41fd8fde04..c222c973fea 100644 --- a/mozilla/layout/html/forms/src/nsSelectControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsSelectControlFrame.cpp @@ -356,7 +356,7 @@ nsSelectControlFrame::PostCreateWidget(nsIPresContext* aPresContext) nsFont font(aPresContext->GetDefaultFixedFont()); GetFont(aPresContext, font); mWidget->SetFont(font); - SetColors(); + SetColors(*aPresContext); // add the options if (!mOptionsAdded) { diff --git a/mozilla/layout/html/forms/src/nsTextControlFrame.cpp b/mozilla/layout/html/forms/src/nsTextControlFrame.cpp index b15762c78c8..250e46bc026 100644 --- a/mozilla/layout/html/forms/src/nsTextControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsTextControlFrame.cpp @@ -282,7 +282,7 @@ nsTextControlFrame::PostCreateWidget(nsIPresContext* aPresContext) nsFont font(aPresContext->GetDefaultFixedFont()); GetFont(aPresContext, font); mWidget->SetFont(font); - SetColors(); + SetColors(*aPresContext); PRUint32 ignore; @@ -301,7 +301,6 @@ nsTextControlFrame::PostCreateWidget(nsIPresContext* aPresContext) NS_RELEASE(text); } else if (NS_OK == mWidget->QueryInterface(kITextAreaWidgetIID,(void**)&textArea)) { textArea->SetText(value, ignore); - mWidget->SetBackgroundColor(NS_RGB(0xFF, 0xFF, 0xFF)); NS_RELEASE(textArea); } } diff --git a/mozilla/layout/html/style/src/nsCSSRendering.cpp b/mozilla/layout/html/style/src/nsCSSRendering.cpp index cfdc9bf8d98..d1b0b11b003 100644 --- a/mozilla/layout/html/style/src/nsCSSRendering.cpp +++ b/mozilla/layout/html/style/src/nsCSSRendering.cpp @@ -36,6 +36,88 @@ #define DASH_LENGTH 3 //3 times longer than dot +// Draw a line, skipping that portion which crosses aGap. aGap defines a rectangle gap +// This services fieldset legends and only works for coords defining horizontal lines. +void nsCSSRendering::DrawLine (nsIRenderingContext& aContext, + nscoord aX1, nscoord aY1, nscoord aX2, nscoord aY2, + nsRect* aGap) +{ + if (nsnull == aGap) { + aContext.DrawLine(aX1, aY1, aX2, aY2); + } else { + nscoord x1 = (aX1 < aX2) ? aX1 : aX2; + nscoord x2 = (aX1 < aX2) ? aX2 : aX1; + nsPoint gapUpperRight(aGap->x + aGap->width, aGap->y); + nsPoint gapLowerRight(aGap->x + aGap->width, aGap->y + aGap->height); + if ((aGap->y <= aY1) && (gapLowerRight.y >= aY2)) { + if ((aGap->x > x1) && (aGap->x < x2)) { + aContext.DrawLine(x1, aY1, aGap->x, aY1); + } + if ((gapLowerRight.x > x1) && (gapLowerRight.x < x2)) { + aContext.DrawLine(gapUpperRight.x, aY2, x2, aY2); + } + } else { + aContext.DrawLine(aX1, aY1, aX2, aY2); + } + } +} + +// Fill a polygon, skipping that portion which crosses aGap. aGap defines a rectangle gap +// This services fieldset legends and only works for points defining a horizontal rectangle +void nsCSSRendering::FillPolygon (nsIRenderingContext& aContext, + const nsPoint aPoints[], + PRInt32 aNumPoints, + nsRect* aGap) +{ + if (nsnull == aGap) { + aContext.FillPolygon(aPoints, aNumPoints); + } else if (4 == aNumPoints) { + nsPoint gapUpperRight(aGap->x + aGap->width, aGap->y); + nsPoint gapLowerRight(aGap->x + aGap->width, aGap->y + aGap->height); + + // sort the 4 points by x + nsPoint points[4]; + for (int i = 0; i < 4; i++) { + points[i] = aPoints[i]; + } + for (i = 0; i < 3; i++) { + for (int j = i+1; j < 4; j++) { + if (points[j].x < points[i].x) { + nsPoint swap = points[i]; + points[i] = points[j]; + points[j] = swap; + } + } + } + + nsPoint upperLeft = (points[0].y <= points[1].y) ? points[0] : points[1]; + nsPoint lowerLeft = (points[0].y <= points[1].y) ? points[1] : points[0]; + nsPoint upperRight = (points[2].y <= points[3].y) ? points[2] : points[3]; + nsPoint lowerRight = (points[2].y <= points[3].y) ? points[3] : points[2]; + + + if ((aGap->y <= upperLeft.y) && (gapLowerRight.y >= lowerRight.y)) { + if ((aGap->x > upperLeft.x) && (aGap->x < upperRight.x)) { + nsPoint leftRect[4]; + leftRect[0] = upperLeft; + leftRect[1] = nsPoint(aGap->x, upperLeft.y); + leftRect[2] = nsPoint(aGap->x, lowerLeft.y); + leftRect[3] = lowerLeft; + aContext.FillPolygon(leftRect, 4); + } + if ((gapUpperRight.x > upperLeft.x) && (gapUpperRight.x < upperRight.x)) { + nsPoint rightRect[4]; + rightRect[0] = nsPoint(gapUpperRight.x, upperRight.y); + rightRect[1] = upperRight; + rightRect[2] = lowerRight; + rightRect[3] = nsPoint(gapLowerRight.x, lowerRight.y); + aContext.FillPolygon(rightRect, 4); + } + } else { + aContext.FillPolygon(aPoints, aNumPoints); + } + } +} /** * Make a bevel color @@ -275,7 +357,8 @@ void nsCSSRendering::DrawSide(nsIRenderingContext& aContext, const nsRect& borderOutside, const nsRect& borderInside, PRBool printing, - nscoord twipsPerPixel) + nscoord twipsPerPixel, + nsRect* aGap) { nsPoint theSide[MAX_POLY_POINTS]; nscolor theColor = borderColors[whichSide]; @@ -296,9 +379,11 @@ void nsCSSRendering::DrawSide(nsIRenderingContext& aContext, BORDER_INSIDE, 0.5f, twipsPerPixel); aContext.SetColor ( MakeBevelColor (whichSide, theStyle, theColor, printing)); if (2 == np) { - aContext.DrawLine (theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y); + //aContext.DrawLine (theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y); + DrawLine (aContext, theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y, aGap); } else { - aContext.FillPolygon (theSide, np); + //aContext.FillPolygon (theSide, np); + FillPolygon (aContext, theSide, np, aGap); } np = MakeSide (theSide, aContext, whichSide, borderOutside, borderInside, BORDER_OUTSIDE, 0.5f, twipsPerPixel); @@ -307,9 +392,11 @@ void nsCSSRendering::DrawSide(nsIRenderingContext& aContext, ? NS_STYLE_BORDER_STYLE_GROOVE : NS_STYLE_BORDER_STYLE_RIDGE, theColor,printing)); if (2 == np) { - aContext.DrawLine (theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y); + //aContext.DrawLine (theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y); + DrawLine (aContext, theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y, aGap); } else { - aContext.FillPolygon (theSide, np); + //aContext.FillPolygon (theSide, np); + FillPolygon (aContext, theSide, np, aGap); } break; @@ -318,9 +405,11 @@ void nsCSSRendering::DrawSide(nsIRenderingContext& aContext, BORDER_FULL, 1.0f, twipsPerPixel); aContext.SetColor (borderColors[whichSide]); if (2 == np) { - aContext.DrawLine (theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y); + //aContext.DrawLine (theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y); + DrawLine (aContext, theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y, aGap); } else { - aContext.FillPolygon (theSide, np); + //aContext.FillPolygon (theSide, np); + FillPolygon (aContext, theSide, np, aGap); } break; @@ -329,16 +418,20 @@ void nsCSSRendering::DrawSide(nsIRenderingContext& aContext, BORDER_INSIDE, 0.333333f, twipsPerPixel); aContext.SetColor (borderColors[whichSide]); if (2 == np) { - aContext.DrawLine (theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y); + //aContext.DrawLine (theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y); + DrawLine (aContext, theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y, aGap); } else { - aContext.FillPolygon (theSide, np); - } + //aContext.FillPolygon (theSide, np); + FillPolygon (aContext, theSide, np, aGap); + } np = MakeSide (theSide, aContext, whichSide, borderOutside, borderInside, BORDER_OUTSIDE, 0.333333f, twipsPerPixel); if (2 == np) { - aContext.DrawLine (theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y); + //aContext.DrawLine (theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y); + DrawLine (aContext, theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y, aGap); } else { - aContext.FillPolygon (theSide, np); + //aContext.FillPolygon (theSide, np); + FillPolygon (aContext, theSide, np, aGap); } break; @@ -348,9 +441,11 @@ void nsCSSRendering::DrawSide(nsIRenderingContext& aContext, BORDER_FULL, 1.0f, twipsPerPixel); aContext.SetColor ( MakeBevelColor (whichSide, theStyle, theColor,printing)); if (2 == np) { - aContext.DrawLine (theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y); + //aContext.DrawLine (theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y); + DrawLine (aContext, theSide[0].x, theSide[0].y, theSide[1].x, theSide[1].y, aGap); } else { - aContext.FillPolygon (theSide, np); + //aContext.FillPolygon (theSide, np); + FillPolygon (aContext, theSide, np, aGap); } break; } @@ -366,7 +461,8 @@ void nsCSSRendering::DrawDashedSides(PRIntn startSide, const nscolor borderColors[], const nsRect& borderOutside, const nsRect& borderInside, - PRIntn aSkipSides) + PRIntn aSkipSides, + nsRect* aGap) { PRIntn dashLength; nsRect dashRect, firstRect, currRect; @@ -595,7 +691,8 @@ void nsCSSRendering::PaintBorder(nsIPresContext& aPresContext, const nsRect& aDirtyRect, const nsRect& aBounds, const nsStyleSpacing& aStyle, - PRIntn aSkipSides) + PRIntn aSkipSides, + nsRect* aGap) { PRIntn cnt; nsMargin border; @@ -624,7 +721,7 @@ void nsCSSRendering::PaintBorder(nsIPresContext& aPresContext, // Draw the dashed/dotted lines first DrawDashedSides(cnt, aRenderingContext, aStyle.mBorderStyle, aStyle.mBorderColor, inside, outside, - aSkipSides); + aSkipSides, aGap); } // Draw all the other sides @@ -632,19 +729,19 @@ void nsCSSRendering::PaintBorder(nsIPresContext& aPresContext, if (0 == (aSkipSides & (1<
-

hey yahoo

- - - an image submit. - +
+  Find it Fast (this wide legend will get fixed)  + + + +
+  
-

+
- password:  
+

+password:  
   +
+ +
+ +

@@ -98,6 +114,22 @@

+ +
+ +
+ +