fieldset, legend support. fixed bug #987

This commit is contained in:
karnaze%netscape.com 1998-10-08 04:38:41 +00:00
Родитель 88edff2205
Коммит 580dde94fe
40 изменённых файлов: 1803 добавлений и 292 удалений

Просмотреть файл

@ -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);

Просмотреть файл

@ -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;

Просмотреть файл

@ -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

Просмотреть файл

@ -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;

Просмотреть файл

@ -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;

Просмотреть файл

@ -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;

Просмотреть файл

@ -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);

Просмотреть файл

@ -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<<NS_SIDE_TOP))) {
DrawSide(aRenderingContext, NS_SIDE_TOP, aStyle.mBorderStyle,
aStyle.mBorderColor, inside, outside, printing, twipsPerPixel);
aStyle.mBorderColor, inside, outside, printing, twipsPerPixel, aGap);
}
if (0 == (aSkipSides & (1<<NS_SIDE_LEFT))) {
DrawSide(aRenderingContext, NS_SIDE_LEFT, aStyle.mBorderStyle,
aStyle.mBorderColor, inside, outside, printing, twipsPerPixel);
aStyle.mBorderColor, inside, outside, printing, twipsPerPixel, aGap);
}
if (0 == (aSkipSides & (1<<NS_SIDE_BOTTOM))) {
DrawSide(aRenderingContext, NS_SIDE_BOTTOM, aStyle.mBorderStyle,
aStyle.mBorderColor, inside, outside, printing, twipsPerPixel);
aStyle.mBorderColor, inside, outside, printing, twipsPerPixel, aGap);
}
if (0 == (aSkipSides & (1<<NS_SIDE_RIGHT))) {
DrawSide(aRenderingContext, NS_SIDE_RIGHT, aStyle.mBorderStyle,
aStyle.mBorderColor, inside, outside, printing, twipsPerPixel);
aStyle.mBorderColor, inside, outside, printing, twipsPerPixel, aGap);
}
}

Просмотреть файл

@ -38,7 +38,8 @@ public:
const nsRect& aDirtyRect,
const nsRect& aBounds,
const nsStyleSpacing& aStyle,
PRIntn aSkipSides);
PRIntn aSkipSides,
nsRect* aGap = 0);
/**
* Render the background for an element using css rendering rules
@ -75,7 +76,8 @@ protected:
const nsRect& borderOutside,
const nsRect& borderInside,
PRBool printing,
nscoord twipsPerPixel);
nscoord twipsPerPixel,
nsRect* aGap = 0);
static void DrawDashedSides(PRIntn startSide,
nsIRenderingContext& aContext,
@ -83,7 +85,17 @@ protected:
const nscolor borderColors[],
const nsRect& borderOutside,
const nsRect& borderInside,
PRIntn aSkipSides);
PRIntn aSkipSides,
nsRect* aGap);
static void DrawLine (nsIRenderingContext& aContext,
nscoord aX1, nscoord aY1, nscoord aX2, nscoord aY2,
nsRect* aGap);
static void FillPolygon (nsIRenderingContext& aContext,
const nsPoint aPoints[],
PRInt32 aNumPoints,
nsRect* aGap);
};
#endif /* nsCSSRendering_h___ */

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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,

Просмотреть файл

@ -168,7 +168,7 @@ public:
* created.
*/
virtual void PostCreateWidget(nsIPresContext* aPresContext);
void SetColors();
void SetColors(nsIPresContext& aPresContext);
virtual void Reset();
virtual PRBool IsSuccessful();

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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

Просмотреть файл

@ -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);
}
}

Просмотреть файл

@ -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);

Просмотреть файл

@ -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);

Просмотреть файл

@ -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;

Просмотреть файл

@ -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);

Просмотреть файл

@ -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

Просмотреть файл

@ -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;

Просмотреть файл

@ -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

Просмотреть файл

@ -33,6 +33,8 @@ CPPSRCS = \
nsRadioControlFrame.cpp \
nsTextControlFrame.cpp \
nsSelectControlFrame.cpp \
nsFieldSetFrame.cpp \
nsLegendFrame.cpp \
$(NULL)
MODULE = raptor

Просмотреть файл

@ -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 \

Просмотреть файл

@ -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);

Просмотреть файл

@ -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);
}
}

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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,

Просмотреть файл

@ -168,7 +168,7 @@ public:
* created.
*/
virtual void PostCreateWidget(nsIPresContext* aPresContext);
void SetColors();
void SetColors(nsIPresContext& aPresContext);
virtual void Reset();
virtual PRBool IsSuccessful();

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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

Просмотреть файл

@ -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) {

Просмотреть файл

@ -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);
}
}

Просмотреть файл

@ -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<<NS_SIDE_TOP))) {
DrawSide(aRenderingContext, NS_SIDE_TOP, aStyle.mBorderStyle,
aStyle.mBorderColor, inside, outside, printing, twipsPerPixel);
aStyle.mBorderColor, inside, outside, printing, twipsPerPixel, aGap);
}
if (0 == (aSkipSides & (1<<NS_SIDE_LEFT))) {
DrawSide(aRenderingContext, NS_SIDE_LEFT, aStyle.mBorderStyle,
aStyle.mBorderColor, inside, outside, printing, twipsPerPixel);
aStyle.mBorderColor, inside, outside, printing, twipsPerPixel, aGap);
}
if (0 == (aSkipSides & (1<<NS_SIDE_BOTTOM))) {
DrawSide(aRenderingContext, NS_SIDE_BOTTOM, aStyle.mBorderStyle,
aStyle.mBorderColor, inside, outside, printing, twipsPerPixel);
aStyle.mBorderColor, inside, outside, printing, twipsPerPixel, aGap);
}
if (0 == (aSkipSides & (1<<NS_SIDE_RIGHT))) {
DrawSide(aRenderingContext, NS_SIDE_RIGHT, aStyle.mBorderStyle,
aStyle.mBorderColor, inside, outside, printing, twipsPerPixel);
aStyle.mBorderColor, inside, outside, printing, twipsPerPixel, aGap);
}
}

Просмотреть файл

@ -38,7 +38,8 @@ public:
const nsRect& aDirtyRect,
const nsRect& aBounds,
const nsStyleSpacing& aStyle,
PRIntn aSkipSides);
PRIntn aSkipSides,
nsRect* aGap = 0);
/**
* Render the background for an element using css rendering rules
@ -75,7 +76,8 @@ protected:
const nsRect& borderOutside,
const nsRect& borderInside,
PRBool printing,
nscoord twipsPerPixel);
nscoord twipsPerPixel,
nsRect* aGap = 0);
static void DrawDashedSides(PRIntn startSide,
nsIRenderingContext& aContext,
@ -83,7 +85,17 @@ protected:
const nscolor borderColors[],
const nsRect& borderOutside,
const nsRect& borderInside,
PRIntn aSkipSides);
PRIntn aSkipSides,
nsRect* aGap);
static void DrawLine (nsIRenderingContext& aContext,
nscoord aX1, nscoord aY1, nscoord aX2, nscoord aY2,
nsRect* aGap);
static void FillPolygon (nsIRenderingContext& aContext,
const nsPoint aPoints[],
PRInt32 aNumPoints,
nsRect* aGap);
};
#endif /* nsCSSRendering_h___ */

Просмотреть файл

@ -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;

Просмотреть файл

@ -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;

Просмотреть файл

@ -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

Просмотреть файл

@ -24,15 +24,18 @@ SELECT#select1 {
<BR>
<FORM METHOD="GET" ACTION="http://search.yahoo.com/bin/search" NAME="searchform">
<P> hey yahoo </P>
<INPUT TYPE="TEXT" NAME="p" SIZE=15 MAXLENGTH=80>
<INPUT TYPE="submit" VALUE="Search">
<input type=image src=raptor.jpg width=50 height=50 name=imageSubmit> an image submit.
<INPUT TYPE="HIDDEN" NAME="a" VALUE="n">
<FIELDSET style="background-color: rgb(200, 220, 240);">
<LEGEND style="background-color:rgb(180, 200, 220);" align=left>&nbsp; Find it <b>Fast</b> (this wide legend will get fixed)&nbsp;</LEGEND>
<INPUT type=text NAME="p" SIZE=15 MAXLENGTH=80 style="margin-right:10px; background-color: rgb(190, 190, 190);">
<INPUT type=submit value="GO">
<INPUT TYPE="HIDDEN" NAME="a" VALUE="n">
</FIELDSET>
&nbsp;&nbsp<INPUT type=image src=raptor.jpg width=50 height=50 name=imageSubmit>
</FORM>
<BR><BR>
<FORM METHOD="POST" ACTION="http://www.mcp.com/cgi-bin/post-query" NAME="echo">
password:&nbsp;&nbsp;<INPUT TYPE="PASSWORD"> <BR>
<BR><BR>
password:&nbsp;&nbsp;<INPUT TYPE="PASSWORD"> <BR>
<textarea name=a rows=4 cols=10 value="a textarea">a textarea</textarea>
&nbsp;&nbsp;
<textarea name=a id=textarea1 value="a textarea">another textarea

Просмотреть файл

@ -1,192 +0,0 @@
<!-- this needs to be tested with various fonts (curier new, serif)
and various font sizes. Nav 4x does not support id= on input -->
<html>
<body>
<FORM METHOD="POST" ACTION="http://www.mcp.com/cgi-bin/post-query" NAME="echo">
<input type=submit>
<BR>
<font size=2><input type=button value="size 2"></font>
<BR>
<font size=2><input type=button value="size 2 and long and long"></font>
<BR>
<font size=3><input type=button value="size 3"></font>
<BR>
<font size=3><input type=button value="size 3 and long and long"></font>
<BR>
<font size=4><input type=button value="size 4"></font>
<BR>
<font size=4><input type=button value="size 4 and long and long"></font>
<BR>
<font size=5><input type=button value="size 5"></font>
<BR>
<font size=5><input type=button value="size 5 and long and long"></font>
<BR>
<font size=6><input type=button value="size 6"></font>
<BR>
<font size=6><input type=button value="size 6 and long and long"></font>
<BR>
<BR>
<font size=2><input type=text value="size 2"></font>
<BR>
<font size=2><input type=text value="size 2 and long and long"></font>
<BR>
<font size=2><input type=text size=5></font>
<BR>
<font size=2><input type=text></font>
<BR>
<font size=3><input type=text value="size 3"></font>
<BR>
<font size=3><input type=text value="size 3 and long and long"></font>
<BR>
<font size=3><input type=text size=5></font>
<BR>
<font size=3><input type=text></font>
<BR>
<font size=4><input type=text value="size 4"></font>
<BR>
<font size=4><input type=text value="size 4 and long and long"></font>
<BR>
<font size=4><input type=text size=5></font>
<BR>
<font size=4><input type=text></font>
<BR>
<font size=5><input type=text value="size 5"></font>
<BR>
<font size=5><input type=text value="size 5 and long and long"></font>
<BR>
<font size=5><input type=text size=5></font>
<BR>
<font size=5><input type=text></font>
<BR>
<font size=6><input type=text value="size 6"></font>
<BR>
<font size=6><input type=text value="size 6 and long and long"></font>
<BR>
<font size=6><input type=text size=5></font>
<BR>
<font size=6><input type=text></font>
<BR>
<font size=2><textarea rows=2 cols=10>size 2</textarea></font>
<BR>
<font size=2><textarea rows=4 cols=10>size 2</textarea></font>
<BR>
<font size=2><textarea>size 2</textarea></font>
<BR>
<font size=3><textarea rows=2 cols=10>size 3</textarea></font>
<BR>
<font size=3><textarea rows=4 cols=10>size 3</textarea></font>
<BR>
<font size=3><textarea>size 3</textarea></font>
<BR>
<font size=4><textarea rows=2 cols=10>size 4</textarea></font>
<BR>
<font size=4><textarea rows=4 cols=10>size 4</textarea></font>
<BR>
<font size=4><textarea>size 4</textarea></font>
<BR>
<font size=5><textarea rows=2 cols=10>size 5</textarea></font>
<BR>
<font size=5><textarea rows=4 cols=10>size 5</textarea></font>
<BR>
<font size=5><textarea>size 5</textarea></font>
<BR>
<font size=6><textarea rows=2 cols=10>size 6</textarea></font>
<BR>
<font size=6><textarea rows=4 cols=10>size 6</textarea></font>
<BR>
<font size=6><textarea>size 6</textarea></font>
<BR>
<font size=2><select size=2>
<option>size 2</option>
<option>option 2</option>
</select></font>
<BR>
<font size=2><select size=2>
<option>size 2</option>
<option>option 2</option>
</select></font>
<BR>
<font size=2><select size=2>
<option>size 2</option>
<option>option 2</option>
<option>option 3</option>
</select></font>
<BR>
<font size=3><select size=1>
<option>size 3</option>
<option>option 2</option>
</select></font>
<BR>
<font size=3><select size=2>
<option>size 3</option>
<option>option 2</option>
</select></font>
<BR>
<font size=3><select size=2>
<option>size 3</option>
<option>option 2</option>
<option>option 3</option>
</select></font>
<BR>
<font size=4><select size=1>
<option>size 4</option>
<option>option 2</option>
</select></font>
<BR>
<font size=4><select size=2>
<option>size 4</option>
<option>option 2</option>
</select></font>
<BR>
<font size=4><select size=2>
<option>size 4</option>
<option>option 2</option>
<option>option 3</option>
</select></font>
<BR>
<font size=5><select size=1>
<option>size 5</option>
<option>option 2</option>
</select></font>
<BR>
<font size=5><select size=2>
<option>size 5</option>
<option>option 2</option>
</select></font>
<BR>
<font size=5><select size=2>
<option>size 5</option>
<option>option 2</option>
<option>option 3</option>
</select></font>
<BR>
<font size=6><select size=1>
<option>size 6</option>
<option>option 2</option>
</select></font>
<BR>
<font size=6><select size=2>
<option>size 6</option>
<option>option 2</option>
</select></font>
<BR>
<font size=6><select size=2>
<option>size 6</option>
<option>option 2</option>
<option>option 3</option>
</select></font>
<input type=reset>
<BR>
<input type=reset value=RESET>
<BR>
<input type=submit>
<BR>
<input type=submit value=SUBMIT>
</FORM>
</body>
</html>