KHTML
SVGImage.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "config.h"
00028 #if ENABLE(SVG)
00029 #include "SVGImage.h"
00030
00031 #include "CachedPage.h"
00032 #include "DocumentLoader.h"
00033 #include "EditCommand.h"
00034 #include "FloatRect.h"
00035 #include "Frame.h"
00036 #include "FrameLoader.h"
00037 #include "FrameView.h"
00038 #include "GraphicsContext.h"
00039 #include "ImageObserver.h"
00040 #include "NotImplemented.h"
00041 #include "Page.h"
00042 #include "RenderView.h"
00043 #include "ResourceError.h"
00044 #include "SVGDocument.h"
00045 #include "SVGLength.h"
00046 #include "SVGRenderSupport.h"
00047 #include "SVGSVGElement.h"
00048 #include "Settings.h"
00049
00050 #include "SVGImageEmptyClients.h"
00051
00052 namespace WebCore {
00053
00054 SVGImage::SVGImage(ImageObserver* observer)
00055 : Image(observer)
00056 , m_document(0)
00057 , m_page(0)
00058 , m_frame(0)
00059 , m_frameView(0)
00060 {
00061 }
00062
00063 SVGImage::~SVGImage()
00064 {
00065 if (m_frame)
00066 m_frame->loader()->frameDetached();
00067 }
00068
00069 void SVGImage::setContainerSize(const IntSize& containerSize)
00070 {
00071 if (containerSize.width() <= 0 || containerSize.height() <= 0)
00072 return;
00073
00074 if (!m_frame || !m_frame->document())
00075 return;
00076 SVGSVGElement* rootElement = static_cast<SVGDocument*>(m_frame->document())->rootElement();
00077 if (!rootElement)
00078 return;
00079
00080 rootElement->setContainerSize(containerSize);
00081 }
00082
00083 bool SVGImage::usesContainerSize() const
00084 {
00085 if (!m_frame || !m_frame->document())
00086 return false;
00087 SVGSVGElement* rootElement = static_cast<SVGDocument*>(m_frame->document())->rootElement();
00088 if (!rootElement)
00089 return false;
00090
00091 return rootElement->hasSetContainerSize();
00092 }
00093
00094 IntSize SVGImage::size() const
00095 {
00096 if (!m_frame || !m_frame->document())
00097 return IntSize();
00098
00099 SVGSVGElement* rootElement = static_cast<SVGDocument*>(m_frame->document())->rootElement();
00100 if (!rootElement)
00101 return IntSize();
00102
00103 SVGLength width = rootElement->width();
00104 SVGLength height = rootElement->height();
00105
00106 IntSize svgSize;
00107 if (width.unitType() == LengthTypePercentage)
00108 svgSize.setWidth(rootElement->relativeWidthValue());
00109 else
00110 svgSize.setWidth(static_cast<int>(width.value()));
00111
00112 if (height.unitType() == LengthTypePercentage)
00113 svgSize.setHeight(rootElement->relativeHeightValue());
00114 else
00115 svgSize.setHeight(static_cast<int>(height.value()));
00116
00117 return svgSize;
00118 }
00119
00120 bool SVGImage::hasRelativeWidth() const
00121 {
00122 if (!m_frame || !m_frame->document())
00123 return false;
00124 SVGSVGElement* rootElement = static_cast<SVGDocument*>(m_frame->document())->rootElement();
00125 if (!rootElement)
00126 return false;
00127
00128 return rootElement->width().unitType() == LengthTypePercentage;
00129 }
00130
00131 bool SVGImage::hasRelativeHeight() const
00132 {
00133 if (!m_frame || !m_frame->document())
00134 return false;
00135 SVGSVGElement* rootElement = static_cast<SVGDocument*>(m_frame->document())->rootElement();
00136 if (!rootElement)
00137 return false;
00138
00139 return rootElement->height().unitType() == LengthTypePercentage;
00140 }
00141
00142 void SVGImage::draw(GraphicsContext* context, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator compositeOp)
00143 {
00144 if (!m_frame)
00145 return;
00146
00147 context->save();
00148 context->setCompositeOperation(compositeOp);
00149 context->clip(enclosingIntRect(dstRect));
00150 if (compositeOp != CompositeSourceOver)
00151 context->beginTransparencyLayer(1.0f);
00152 context->translate(dstRect.location().x(), dstRect.location().y());
00153 context->scale(FloatSize(dstRect.width()/srcRect.width(), dstRect.height()/srcRect.height()));
00154
00155 if (m_frame->view()->needsLayout())
00156 m_frame->view()->layout();
00157 m_frame->paint(context, enclosingIntRect(srcRect));
00158
00159 if (compositeOp != CompositeSourceOver)
00160 context->endTransparencyLayer();
00161
00162 context->restore();
00163
00164 if (imageObserver())
00165 imageObserver()->didDraw(this);
00166 }
00167
00168 NativeImagePtr SVGImage::nativeImageForCurrentFrame()
00169 {
00170
00171
00172
00173 if (!m_frameCache) {
00174 m_frameCache.set(ImageBuffer::create(size(), false).release());
00175 if (!m_frameCache)
00176 return 0;
00177 renderSubtreeToImage(m_frameCache.get(), m_frame->contentRenderer());
00178 }
00179 #if PLATFORM(CG)
00180 return m_frameCache->cgImage();
00181 #elif PLATFORM(QT)
00182 return m_frameCache->pixmap();
00183 #elif PLATFORM(CAIRO)
00184 return m_frameCache->surface();
00185 #else
00186 notImplemented();
00187 return 0;
00188 #endif
00189 }
00190
00191 bool SVGImage::dataChanged(bool allDataReceived)
00192 {
00193 int length = m_data->size();
00194 if (!length)
00195 return true;
00196
00197 if (allDataReceived) {
00198 static ChromeClient* dummyChromeClient = new SVGEmptyChromeClient;
00199 static FrameLoaderClient* dummyFrameLoaderClient = new SVGEmptyFrameLoaderClient;
00200 static EditorClient* dummyEditorClient = new SVGEmptyEditorClient;
00201 static ContextMenuClient* dummyContextMenuClient = new SVGEmptyContextMenuClient;
00202 static DragClient* dummyDragClient = new SVGEmptyDragClient;
00203 static InspectorClient* dummyInspectorClient = new SVGEmptyInspectorClient;
00204
00205
00206
00207 m_page.set(new Page(dummyChromeClient, dummyContextMenuClient, dummyEditorClient, dummyDragClient, dummyInspectorClient));
00208 m_page->settings()->setJavaScriptEnabled(false);
00209
00210 m_frame = new Frame(m_page.get(), 0, dummyFrameLoaderClient);
00211 m_frameView = new FrameView(m_frame.get());
00212 m_frameView->deref();
00213 m_frame->setView(m_frameView.get());
00214 m_frame->init();
00215 ResourceRequest fakeRequest(KURL(""));
00216 m_frame->loader()->load(fakeRequest);
00217 m_frame->loader()->cancelContentPolicyCheck();
00218 m_frame->loader()->commitProvisionalLoad(0);
00219 m_frame->loader()->setResponseMIMEType("image/svg+xml");
00220 m_frame->loader()->begin(KURL());
00221 m_frame->loader()->write(m_data->data(), m_data->size());
00222 m_frame->loader()->end();
00223 m_frameView->setTransparent(true);
00224 }
00225 return m_frameView;
00226 }
00227
00228 }
00229
00230 #endif // ENABLE(SVG)