Mozilla/mozilla/layout/html/base/src/nsHTMLImage.cpp
troy%netscape.com 1648bbf5e6 Added background color to image loading member functions
git-svn-id: svn://10.0.0.236/trunk@5690 18797224-902f-48f8-a5cc-f745e15eee43
1998-07-16 04:34:59 +00:00

785 lines
23 KiB
C++

/* -*- 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.
*/
#include "nsHTMLParts.h"
#include "nsHTMLImage.h"
#include "nsHTMLTagContent.h"
#include "nsString.h"
#include "nsLeafFrame.h"
#include "nsIPresContext.h"
#include "nsIRenderingContext.h"
#include "nsIFrameImageLoader.h"
#include "nsIPresShell.h"
#include "nsHTMLIIDs.h"
#include "nsIImage.h"
#include "nsIWidget.h"
#include "nsHTMLAtoms.h"
#include "nsIHTMLAttributes.h"
#include "nsIDocument.h"
#include "nsIHTMLDocument.h"
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
#include "nsIImageMap.h"
#include "nsILinkHandler.h"
#include "nsIURL.h"
#include "nsCSSLayout.h"
#include "nsHTMLBase.h"
#include "prprf.h"
#include "nsISizeOfHandler.h"
#define BROKEN_IMAGE_URL "resource:/res/html/broken-image.gif"
// XXX image frame layout can be 100% decoupled from the content
// object; all it needs are attributes to work properly
static NS_DEFINE_IID(kIHTMLDocumentIID, NS_IHTMLDOCUMENT_IID);
#define nsHTMLImageSuper nsHTMLTagContent
class nsHTMLImage : public nsHTMLImageSuper {
public:
nsHTMLImage(nsIAtom* aTag);
NS_IMETHOD SizeOf(nsISizeOfHandler* aHandler) const;
virtual nsresult CreateFrame(nsIPresContext* aPresContext,
nsIFrame* aParentFrame,
nsIStyleContext* aStyleContext,
nsIFrame*& aResult);
virtual void SetAttribute(nsIAtom* aAttribute, const nsString& aValue);
virtual void MapAttributesInto(nsIStyleContext* aContext,
nsIPresContext* aPresContext);
protected:
virtual ~nsHTMLImage();
void SizeOfWithoutThis(nsISizeOfHandler* aHandler) const;
virtual nsContentAttr AttributeToString(nsIAtom* aAttribute,
nsHTMLValue& aValue,
nsString& aResult) const;
};
#define ImageFrameSuper nsLeafFrame
class ImageFrame : public ImageFrameSuper {
public:
ImageFrame(nsIContent* aContent, nsIFrame* aParentFrame);
NS_IMETHOD DeleteFrame();
NS_IMETHOD SizeOf(nsISizeOfHandler* aHandler) const;
NS_IMETHOD Paint(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect);
NS_METHOD HandleEvent(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsEventStatus& aEventStatus);
NS_IMETHOD GetCursorAt(nsIPresContext& aPresContext,
const nsPoint& aPoint,
nsIFrame** aFrame,
PRInt32& aCursor);
protected:
virtual ~ImageFrame();
void SizeOfWithoutThis(nsISizeOfHandler* aHandler) const;
virtual void GetDesiredSize(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
nsReflowMetrics& aDesiredSize);
nsIImageMap* GetImageMap();
nsHTMLImageLoader mImageLoader;
nsIImageMap* mImageMap;
void TriggerLink(nsIPresContext& aPresContext,
const nsString& aURLSpec,
const nsString& aTargetSpec,
PRBool aClick);
PRBool IsServerImageMap();
PRIntn GetSuppress();
};
// Value's for mSuppress
#define SUPPRESS_UNSET 0
#define DONT_SUPPRESS 1
#define SUPPRESS 2
#define DEFAULT_SUPPRESS 3
// Default alignment value (so we can tell an unset value from a set value)
#define ALIGN_UNSET PRUint8(-1)
//----------------------------------------------------------------------
nsHTMLImageLoader::nsHTMLImageLoader()
{
mImageLoader = nsnull;
mLoadImageFailed = PR_FALSE;
mLoadBrokenImageFailed = PR_FALSE;
mURLSpec = nsnull;
}
nsHTMLImageLoader::~nsHTMLImageLoader()
{
NS_IF_RELEASE(mImageLoader);
if (nsnull != mURLSpec) {
delete mURLSpec;
}
}
void
nsHTMLImageLoader::SizeOf(nsISizeOfHandler* aHandler) const
{
aHandler->Add(sizeof(*this));
if (!aHandler->HaveSeen(mURLSpec)) {
mURLSpec->SizeOf(aHandler);
}
if (!aHandler->HaveSeen(mImageLoader)) {
mImageLoader->SizeOf(aHandler);
}
}
nsIImage*
nsHTMLImageLoader::GetImage()
{
nsIImage* image = nsnull;
if (nsnull != mImageLoader) {
mImageLoader->GetImage(image);
}
return image;
}
nsresult
nsHTMLImageLoader::SetURL(const nsString& aURLSpec)
{
if (nsnull != mURLSpec) {
delete mURLSpec;
}
mURLSpec = new nsString(aURLSpec);
if (nsnull == mURLSpec) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
nsresult
nsHTMLImageLoader::LoadImage(nsIPresContext* aPresContext,
nsIFrame* aForFrame,
PRBool aNeedSizeUpdate,
PRIntn& aLoadStatus)
{
aLoadStatus = NS_IMAGE_LOAD_STATUS_NONE;
// Get absolute url the first time through
nsresult rv;
nsAutoString src;
if (mLoadImageFailed || (nsnull == mURLSpec)) {
src.Append(BROKEN_IMAGE_URL);
} else {
nsAutoString baseURL;
// Get documentURL
nsIPresShell* shell;
shell = aPresContext->GetShell();
nsIDocument* doc = shell->GetDocument();
nsIURL* docURL = doc->GetDocumentURL();
// Create an absolute URL
nsresult rv = NS_MakeAbsoluteURL(docURL, baseURL, *mURLSpec, src);
// Release references
NS_RELEASE(shell);
NS_RELEASE(docURL);
NS_RELEASE(doc);
if (NS_OK != rv) {
return rv;
}
}
if (nsnull == mImageLoader) {
// Start image loading. Note that we don't specify a background color
// so transparent images are always rendered using a transparency mask
rv = aPresContext->LoadImage(src, nsnull, aForFrame, aNeedSizeUpdate,
mImageLoader);
if (NS_OK != rv) {
return rv;
}
}
// Examine current image load status
mImageLoader->GetImageLoadStatus(aLoadStatus);
if (0 != (aLoadStatus & NS_IMAGE_LOAD_STATUS_ERROR)) {
NS_RELEASE(mImageLoader);
if (mLoadImageFailed) {
// We are doomed. Loading the broken image has just failed.
mLoadBrokenImageFailed = PR_TRUE;
}
else {
// Try again, this time using the broke-image url
mLoadImageFailed = PR_TRUE;
return LoadImage(aPresContext, aForFrame, aNeedSizeUpdate, aLoadStatus);
}
}
return NS_OK;
}
void
nsHTMLImageLoader::GetDesiredSize(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
nsReflowMetrics& aDesiredSize)
{
nsSize styleSize;
PRIntn ss = nsCSSLayout::GetStyleSize(aPresContext, aReflowState, styleSize);
PRIntn loadStatus;
if (0 != ss) {
if (NS_SIZE_HAS_BOTH == ss) {
LoadImage(aPresContext, aReflowState.frame, PR_FALSE, loadStatus);
aDesiredSize.width = styleSize.width;
aDesiredSize.height = styleSize.height;
}
else {
// Preserve aspect ratio of image with unbound dimension.
LoadImage(aPresContext, aReflowState.frame, PR_TRUE, loadStatus);
if ((0 == (loadStatus & NS_IMAGE_LOAD_STATUS_SIZE_AVAILABLE)) ||
(nsnull == mImageLoader)) {
// Provide a dummy size for now; later on when the image size
// shows up we will reflow to the new size.
aDesiredSize.width = 1;
aDesiredSize.height = 1;
}
else {
float p2t = aPresContext->GetPixelsToTwips();
nsSize imageSize;
mImageLoader->GetSize(imageSize);
float imageWidth = imageSize.width * p2t;
float imageHeight = imageSize.height * p2t;
if (0.0f != imageHeight) {
if (0 != (ss & NS_SIZE_HAS_WIDTH)) {
// We have a width, and an auto height. Compute height
// from width.
aDesiredSize.width = styleSize.width;
aDesiredSize.height =
nscoord(styleSize.width * imageHeight / imageWidth);
}
else {
// We have a height and an auto width. Compute width from
// height.
aDesiredSize.height = styleSize.height;
aDesiredSize.width =
nscoord(styleSize.height * imageWidth / imageHeight);
}
}
else {
// Screwy image
aDesiredSize.width = 1;
aDesiredSize.height = 1;
}
}
}
}
else {
LoadImage(aPresContext, aReflowState.frame, PR_TRUE, loadStatus);
if ((0 == (loadStatus & NS_IMAGE_LOAD_STATUS_SIZE_AVAILABLE)) ||
(nsnull == mImageLoader)) {
// Provide a dummy size for now; later on when the image size
// shows up we will reflow to the new size.
aDesiredSize.width = 1;
aDesiredSize.height = 1;
} else {
float p2t = aPresContext->GetPixelsToTwips();
nsSize imageSize;
mImageLoader->GetSize(imageSize);
aDesiredSize.width = nscoord(imageSize.width * p2t);
aDesiredSize.height = nscoord(imageSize.height * p2t);
}
}
}
//----------------------------------------------------------------------
ImageFrame::ImageFrame(nsIContent* aContent, nsIFrame* aParentFrame)
: nsLeafFrame(aContent, aParentFrame)
{
}
ImageFrame::~ImageFrame()
{
}
NS_METHOD
ImageFrame::DeleteFrame()
{
NS_IF_RELEASE(mImageMap);
// Release image loader first so that it's refcnt can go to zero
mImageLoader.DestroyLoader();
return nsLeafFrame::DeleteFrame();
}
NS_IMETHODIMP
ImageFrame::SizeOf(nsISizeOfHandler* aHandler) const
{
aHandler->Add(sizeof(*this));
ImageFrame::SizeOfWithoutThis(aHandler);
return NS_OK;
}
void
ImageFrame::SizeOfWithoutThis(nsISizeOfHandler* aHandler) const
{
ImageFrameSuper::SizeOfWithoutThis(aHandler);
mImageLoader.SizeOf(aHandler);
if (!aHandler->HaveSeen(mImageMap)) {
mImageMap->SizeOf(aHandler);
}
}
void
ImageFrame::GetDesiredSize(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
nsReflowMetrics& aDesiredSize)
{
nsHTMLBase::CreateViewForFrame(aPresContext, this, mStyleContext, PR_TRUE);
// Setup url before starting the image load
nsAutoString src;
if (eContentAttr_HasValue == mContent->GetAttribute("SRC", src)) {
mImageLoader.SetURL(src);
}
mImageLoader.GetDesiredSize(aPresContext, aReflowState, aDesiredSize);
}
NS_METHOD
ImageFrame::Paint(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect)
{
if ((0 == mRect.width) || (0 == mRect.height)) {
// Do not render when given a zero area. This avoids some useless
// scaling work while we wait for our image dimensions to arrive
// asynchronously.
return NS_OK;
}
const nsStyleDisplay* disp =
(const nsStyleDisplay*)mStyleContext->GetStyleData(eStyleStruct_Display);
if (disp->mVisible) {
// First paint background and borders
nsLeafFrame::Paint(aPresContext, aRenderingContext, aDirtyRect);
// XXX when we don't have the image, draw the we-don't-have-an-image look
nsIImage* image = mImageLoader.GetImage();
if (nsnull == image) {
// No image yet
return NS_OK;
}
// Now render the image into our inner area (the area without the
// borders and padding)
nsRect inner;
GetInnerArea(&aPresContext, inner);
if (mImageLoader.GetLoadImageFailed()) {
float p2t = aPresContext.GetPixelsToTwips();
inner.width = nscoord(p2t * image->GetWidth());
inner.height = nscoord(p2t * image->GetHeight());
}
aRenderingContext.DrawImage(image, inner);
if (GetShowFrameBorders()) {
nsIImageMap* map = GetImageMap();
if (nsnull != map) {
aRenderingContext.SetColor(NS_RGB(0, 0, 0));
aRenderingContext.PushState();
aRenderingContext.Translate(inner.x, inner.y);
map->Draw(aPresContext, aRenderingContext);
aRenderingContext.PopState();
}
}
}
return NS_OK;
}
nsIImageMap*
ImageFrame::GetImageMap()
{
if (nsnull == mImageMap) {
nsAutoString usemap;
mContent->GetAttribute("usemap", usemap);
if (0 == usemap.Length()) {
return nsnull;
}
nsIDocument* doc = nsnull;
mContent->GetDocument(doc);
if (nsnull == doc) {
return nsnull;
}
if (usemap.First() == '#') {
usemap.Cut(0, 1);
}
nsIHTMLDocument* hdoc;
nsresult rv = doc->QueryInterface(kIHTMLDocumentIID, (void**)&hdoc);
NS_RELEASE(doc);
if (NS_OK == rv) {
nsIImageMap* map;
rv = hdoc->GetImageMap(usemap, &map);
NS_RELEASE(hdoc);
if (NS_OK == rv) {
mImageMap = map;
}
}
}
NS_IF_ADDREF(mImageMap);
return mImageMap;
}
void
ImageFrame::TriggerLink(nsIPresContext& aPresContext,
const nsString& aURLSpec,
const nsString& aTargetSpec,
PRBool aClick)
{
nsILinkHandler* handler = nsnull;
aPresContext.GetLinkHandler(&handler);
if (nsnull != handler) {
if (aClick) {
handler->OnLinkClick(this, aURLSpec, aTargetSpec);
}
else {
handler->OnOverLink(this, aURLSpec, aTargetSpec);
}
}
}
PRBool
ImageFrame::IsServerImageMap()
{
nsAutoString ismap;
return eContentAttr_HasValue == mContent->GetAttribute("ismap", ismap);
}
PRIntn
ImageFrame::GetSuppress()
{
nsAutoString s;
if (eContentAttr_HasValue == mContent->GetAttribute("ismap", s)) {
if (s.EqualsIgnoreCase("true")) {
return SUPPRESS;
} else if (s.EqualsIgnoreCase("false")) {
return DONT_SUPPRESS;
}
}
return DEFAULT_SUPPRESS;
}
// XXX what should clicks on transparent pixels do?
NS_METHOD
ImageFrame::HandleEvent(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsEventStatus& aEventStatus)
{
nsIImageMap* map;
aEventStatus = nsEventStatus_eIgnore;
switch (aEvent->message) {
case NS_MOUSE_LEFT_BUTTON_UP:
case NS_MOUSE_MOVE:
map = GetImageMap();
if ((nsnull != map) || IsServerImageMap()) {
nsIURL* docURL = nsnull;
nsIDocument* doc = nsnull;
mContent->GetDocument(doc);
if (nsnull != doc) {
docURL = doc->GetDocumentURL();
NS_RELEASE(doc);
}
// Ask map if the x,y coordinates are in a clickable area
float t2p = aPresContext.GetTwipsToPixels();
nsAutoString absURL, target, altText;
PRBool suppress;
if (nsnull != map) {
// Subtract out border and padding here so that we are looking
// at the right coordinates. Hit detection against area tags
// is done after the mouse wanders over the image, not over
// the image's borders.
nsRect inner;
GetInnerArea(&aPresContext, inner);
nscoord x = nscoord(t2p * (aEvent->point.x - inner.x));
nscoord y = nscoord(t2p * (aEvent->point.y - inner.y));
nsresult r = map->IsInside(x, y, docURL, absURL, target, altText,
&suppress);
NS_IF_RELEASE(docURL);
NS_RELEASE(map);
if (NS_OK == r) {
// We hit a clickable area. Time to go somewhere...
PRBool clicked = PR_FALSE;
if (aEvent->message == NS_MOUSE_LEFT_BUTTON_UP) {
aEventStatus = nsEventStatus_eConsumeNoDefault;
clicked = PR_TRUE;
}
TriggerLink(aPresContext, absURL, target, clicked);
}
}
else {
suppress = GetSuppress();
nsAutoString baseURL;/* XXX */
nsAutoString src;
mContent->GetAttribute("src", src);
NS_MakeAbsoluteURL(docURL, baseURL, src, absURL);
// Note: We don't subtract out the border/padding here to remain
// compatible with navigator. [ick]
nscoord x = nscoord(t2p * aEvent->point.x);
nscoord y = nscoord(t2p * aEvent->point.y);
char cbuf[50];
PR_snprintf(cbuf, sizeof(cbuf), "?%d,%d", x, y);
absURL.Append(cbuf);
PRBool clicked = PR_FALSE;
if (aEvent->message == NS_MOUSE_LEFT_BUTTON_UP) {
aEventStatus = nsEventStatus_eConsumeNoDefault;
clicked = PR_TRUE;
}
TriggerLink(aPresContext, absURL, target, clicked);
}
break;
}
// FALL THROUGH
default:
// Let default event handler deal with it
return nsLeafFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
}
return NS_OK;
}
NS_METHOD
ImageFrame::GetCursorAt(nsIPresContext& aPresContext,
const nsPoint& aPoint,
nsIFrame** aFrame,
PRInt32& aCursor)
{
// The default cursor is to have no cursor
aCursor = NS_STYLE_CURSOR_INHERIT;
const nsStyleColor* styleColor = (const nsStyleColor*)
mStyleContext->GetStyleData(eStyleStruct_Color);
if (styleColor->mCursor != NS_STYLE_CURSOR_INHERIT) {
// If we have a particular cursor, use it
*aFrame = this;
aCursor = (PRInt32) styleColor->mCursor;
}
nsIImageMap* map = GetImageMap();
if (nsnull != map) {
nsRect inner;
GetInnerArea(&aPresContext, inner);
aCursor = NS_STYLE_CURSOR_DEFAULT;
float t2p = aPresContext.GetTwipsToPixels();
nscoord x = nscoord(t2p * (aPoint.x - inner.x));
nscoord y = nscoord(t2p * (aPoint.y - inner.y));
if (NS_OK == map->IsInside(x, y)) {
aCursor = NS_STYLE_CURSOR_HAND;
}
NS_RELEASE(map);
}
return NS_OK;
}
//----------------------------------------------------------------------
nsHTMLImage::nsHTMLImage(nsIAtom* aTag)
: nsHTMLTagContent(aTag)
{
}
nsHTMLImage::~nsHTMLImage()
{
}
NS_IMETHODIMP
nsHTMLImage::SizeOf(nsISizeOfHandler* aHandler) const
{
aHandler->Add(sizeof(*this));
nsHTMLImage::SizeOfWithoutThis(aHandler);
return NS_OK;
}
void
nsHTMLImage::SizeOfWithoutThis(nsISizeOfHandler* aHandler) const
{
}
void
nsHTMLImage::SetAttribute(nsIAtom* aAttribute, const nsString& aString)
{
nsHTMLValue val;
if (aAttribute == nsHTMLAtoms::ismap) {
val.SetEmptyValue();
nsHTMLTagContent::SetAttribute(aAttribute, val);
}
else if (aAttribute == nsHTMLAtoms::usemap) {
nsAutoString usemap(aString);
usemap.StripWhitespace();
val.SetStringValue(usemap);
nsHTMLTagContent::SetAttribute(aAttribute, val);
}
else if (aAttribute == nsHTMLAtoms::align) {
if (ParseAlignParam(aString, val)) {
// Reflect the attribute into the syle system
nsHTMLTagContent::SetAttribute(aAttribute, val);
}
else {
val.SetStringValue(aString);
nsHTMLTagContent::SetAttribute(aAttribute, val);
}
}
else if (aAttribute == nsHTMLAtoms::src) {
nsAutoString src(aString);
src.StripWhitespace();
val.SetStringValue(src);
nsHTMLTagContent::SetAttribute(aAttribute, val);
}
else if (aAttribute == nsHTMLAtoms::lowsrc) {
nsAutoString lowsrc(aString);
lowsrc.StripWhitespace();
val.SetStringValue(lowsrc);
nsHTMLTagContent::SetAttribute(aAttribute, val);
}
else if (aAttribute == nsHTMLAtoms::alt) {
val.SetStringValue(aString);
nsHTMLTagContent::SetAttribute(aAttribute, val);
}
else if (aAttribute == nsHTMLAtoms::suppress) {
PRIntn suppress = DEFAULT_SUPPRESS;
if (aString.EqualsIgnoreCase("true")) {
suppress = SUPPRESS;
}
else if (aString.EqualsIgnoreCase("false")) {
suppress = DONT_SUPPRESS;
}
val.SetIntValue(suppress, eHTMLUnit_Enumerated);
nsHTMLTagContent::SetAttribute(aAttribute, val);
}
else if (ParseImageProperty(aAttribute, aString, val)) {
nsHTMLTagContent::SetAttribute(aAttribute, val);
}
else {
// Use default attribute catching code
nsHTMLImageSuper::SetAttribute(aAttribute, aString);
}
}
nsContentAttr
nsHTMLImage::AttributeToString(nsIAtom* aAttribute,
nsHTMLValue& aValue,
nsString& aResult) const
{
nsContentAttr ca = eContentAttr_NotThere;
if (aAttribute == nsHTMLAtoms::align) {
if (eHTMLUnit_Enumerated == aValue.GetUnit()) {
AlignParamToString(aValue, aResult);
ca = eContentAttr_HasValue;
}
}
else if (aAttribute == nsHTMLAtoms::suppress) {
aResult.Truncate();
switch (aValue.GetIntValue()) {
case SUPPRESS: aResult.Append("true"); break;
case DONT_SUPPRESS: aResult.Append("false"); break;
case DEFAULT_SUPPRESS: break;
}
ca = eContentAttr_HasValue;
}
else if (ImagePropertyToString(aAttribute, aValue, aResult)) {
ca = eContentAttr_HasValue;
}
return ca;
}
void
nsHTMLImage::MapAttributesInto(nsIStyleContext* aContext,
nsIPresContext* aPresContext)
{
if (nsnull != mAttributes) {
nsHTMLValue value;
GetAttribute(nsHTMLAtoms::align, value);
if (value.GetUnit() == eHTMLUnit_Enumerated) {
PRUint8 align = value.GetIntValue();
nsStyleDisplay* display = (nsStyleDisplay*)
aContext->GetMutableStyleData(eStyleStruct_Display);
nsStyleText* text = (nsStyleText*)
aContext->GetMutableStyleData(eStyleStruct_Text);
nsStyleSpacing* spacing = (nsStyleSpacing*)
aContext->GetMutableStyleData(eStyleStruct_Spacing);
float p2t = aPresContext->GetPixelsToTwips();
nsStyleCoord three(nscoord(p2t*3));
switch (align) {
case NS_STYLE_TEXT_ALIGN_LEFT:
display->mFloats = NS_STYLE_FLOAT_LEFT;
spacing->mMargin.SetLeft(three);
spacing->mMargin.SetRight(three);
break;
case NS_STYLE_TEXT_ALIGN_RIGHT:
display->mFloats = NS_STYLE_FLOAT_RIGHT;
spacing->mMargin.SetLeft(three);
spacing->mMargin.SetRight(three);
break;
default:
text->mVerticalAlign.SetIntValue(align, eStyleUnit_Enumerated);
break;
}
}
}
MapImagePropertiesInto(aContext, aPresContext);
MapImageBorderInto(aContext, aPresContext, nsnull);
}
nsresult
nsHTMLImage::CreateFrame(nsIPresContext* aPresContext,
nsIFrame* aParentFrame,
nsIStyleContext* aStyleContext,
nsIFrame*& aResult)
{
ImageFrame* frame = new ImageFrame(this, aParentFrame);
if (nsnull == frame) {
return NS_ERROR_OUT_OF_MEMORY;
}
aResult = frame;
frame->SetStyleContext(aPresContext, aStyleContext);
return NS_OK;
}
nsresult
NS_NewHTMLImage(nsIHTMLContent** aInstancePtrResult,
nsIAtom* aTag)
{
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
if (nsnull == aInstancePtrResult) {
return NS_ERROR_NULL_POINTER;
}
nsIHTMLContent* img = new nsHTMLImage(aTag);
if (nsnull == img) {
return NS_ERROR_OUT_OF_MEMORY;
}
return img->QueryInterface(kIHTMLContentIID, (void **) aInstancePtrResult);
}