Changeset 21686 in webkit
- Timestamp:
- May 23, 2007 6:01:02 PM (17 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r21685 r21686 1 2007-05-23 Anders Carlsson <andersca@apple.com> 2 3 Reviewed by Geoff. 4 5 <rdar://problem/3663808> Resize large images to fit in the browser window 6 7 * WebCore.exp: 8 Add new settings method. 9 10 * loader/ImageDocument.cpp: 11 (WebCore::ImageEventListener::ImageEventListener): 12 New class that handles resize events and click events and forwards them to the image document. 13 14 (WebCore::ImageTokenizer::ImageTokenizer): 15 (WebCore::ImageTokenizer::writeRawData): 16 (WebCore::ImageTokenizer::finish): 17 (WebCore::ImageDocument::ImageDocument): 18 (WebCore::ImageDocument::createDocumentStructure): 19 (WebCore::ImageDocument::cachedImage): 20 Let the ImageDocument class keep track of its document structure. 21 22 (WebCore::ImageDocument::scale): 23 Returns the scale that should be used when resizing the image. 24 25 (WebCore::ImageDocument::resizeImage): 26 Update the image size. 27 28 (WebCore::ImageDocument::imageClicked): 29 Toggle between resized and not resized. When restoring the size, scroll the image so that the area under 30 the mouse stays the same. 31 32 (WebCore::ImageDocument::imageChanged): 33 When the image size is known, resize the image if needed. 34 35 (WebCore::ImageDocument::restoreImageSize): 36 Restore the image size. 37 38 (WebCore::ImageDocument::imageNeedsResizing): 39 Return whether the image is too big for its window or not. 40 41 (WebCore::ImageDocument::windowSizeChanged): 42 Called when the window's size changes. Determine if the window fits or not and resize it if it doesn't fit. 43 44 (WebCore::ImageEventListener::handleEvent): 45 Forward events to the image document. 46 47 * page/Settings.cpp: 48 (WebCore::Settings::Settings): 49 (WebCore::Settings::setEnableAutomaticImageResizing): 50 * page/Settings.h: 51 (WebCore::Settings::enableAutomaticImageResizing): 52 Add new setting. 53 1 54 2007-05-23 Anders Carlsson <andersca@apple.com> 2 55 -
trunk/WebCore/WebCore.exp
r21596 r21686 447 447 __ZN7WebCore8Settings26setDefaultTextEncodingNameERKNS_6StringE 448 448 __ZN7WebCore8Settings27setLoadsImagesAutomaticallyEb 449 __ZN7WebCore8Settings31setShrinksStandaloneImagesToFitEb 449 450 __ZN7WebCore8Settings34setNeedsAcrobatFrameReloadingQuirkEb 450 451 __ZN7WebCore8Settings40setJavaScriptCanOpenWindowsAutomaticallyEb -
trunk/WebCore/loader/ImageDocument.cpp
r21179 r21686 29 29 #include "DocumentLoader.h" 30 30 #include "Element.h" 31 #include "EventListener.h" 32 #include "EventNames.h" 31 33 #include "Frame.h" 32 34 #include "FrameLoader.h" 35 #include "FrameView.h" 33 36 #include "HTMLImageElement.h" 34 37 #include "HTMLNames.h" 38 #include "MouseEvent.h" 39 #include "Page.h" 35 40 #include "SegmentedString.h" 41 #include "Settings.h" 36 42 #include "Text.h" 37 43 #include "XMLTokenizer.h" … … 41 47 #endif 42 48 49 using std::min; 50 43 51 namespace WebCore { 44 52 53 using namespace EventNames; 45 54 using namespace HTMLNames; 55 56 class ImageEventListener : public EventListener { 57 public: 58 ImageEventListener(ImageDocument* doc) : m_doc(doc) { } 59 60 virtual void handleEvent(Event*, bool isWindowEvent); 61 private: 62 ImageDocument* m_doc; 63 }; 46 64 47 65 class ImageTokenizer : public Tokenizer { 48 66 public: 49 ImageTokenizer( Document* doc) : m_doc(doc), m_imageElement(0) {}67 ImageTokenizer(ImageDocument* doc) : m_doc(doc) {} 50 68 51 69 virtual bool write(const SegmentedString&, bool appendData); … … 55 73 virtual bool wantsRawData() const { return true; } 56 74 virtual bool writeRawData(const char* data, int len); 57 58 void createDocumentStructure();59 75 private: 60 Document* m_doc; 61 HTMLImageElement* m_imageElement; 76 ImageDocument* m_doc; 62 77 }; 63 78 … … 68 83 } 69 84 70 void ImageTokenizer::createDocumentStructure()71 {72 ExceptionCode ec;73 74 RefPtr<Element> rootElement = m_doc->createElementNS(xhtmlNamespaceURI, "html", ec);75 m_doc->appendChild(rootElement, ec);76 77 RefPtr<Element> body = m_doc->createElementNS(xhtmlNamespaceURI, "body", ec);78 body->setAttribute(styleAttr, "margin: 0px;");79 80 rootElement->appendChild(body, ec);81 82 RefPtr<Element> imageElement = m_doc->createElementNS(xhtmlNamespaceURI, "img", ec);83 84 m_imageElement = static_cast<HTMLImageElement *>(imageElement.get());85 m_imageElement->setAttribute(styleAttr, "-webkit-user-select: none");86 m_imageElement->setLoadManually(true);87 m_imageElement->setSrc(m_doc->URL());88 89 body->appendChild(imageElement, ec);90 }91 92 85 bool ImageTokenizer::writeRawData(const char* data, int len) 93 86 { 94 if (!m_imageElement) 95 createDocumentStructure(); 96 97 CachedImage* cachedImage = m_imageElement->cachedImage(); 87 CachedImage* cachedImage = m_doc->cachedImage(); 98 88 cachedImage->data(m_doc->frame()->loader()->documentLoader()->mainResourceData(), false); 99 89 90 m_doc->imageChanged(); 91 100 92 return false; 101 93 } … … 103 95 void ImageTokenizer::finish() 104 96 { 105 if (!m_parserStopped && m_ imageElement) {106 CachedImage* cachedImage = m_ imageElement->cachedImage();97 if (!m_parserStopped && m_doc->imageElement()) { 98 CachedImage* cachedImage = m_doc->cachedImage(); 107 99 cachedImage->data(m_doc->frame()->loader()->documentLoader()->mainResourceData(), true); 108 100 cachedImage->finish(); … … 127 119 ImageDocument::ImageDocument(DOMImplementation* implementation, Frame* frame) 128 120 : HTMLDocument(implementation, frame) 129 { 121 , m_imageElement(0) 122 , m_imageSizeIsKnown(false) 123 , m_didShrinkImage(false) 124 , m_shouldShrinkImage(true) 125 { 126 setParseMode(Compat); 130 127 } 131 128 … … 134 131 return new ImageTokenizer(this); 135 132 } 136 137 } 133 134 void ImageDocument::createDocumentStructure() 135 { 136 ExceptionCode ec; 137 138 RefPtr<Element> rootElement = createElementNS(xhtmlNamespaceURI, "html", ec); 139 appendChild(rootElement, ec); 140 141 RefPtr<Element> body = createElementNS(xhtmlNamespaceURI, "body", ec); 142 body->setAttribute(styleAttr, "margin: 0px;"); 143 144 rootElement->appendChild(body, ec); 145 146 RefPtr<Element> imageElement = createElementNS(xhtmlNamespaceURI, "img", ec); 147 148 m_imageElement = static_cast<HTMLImageElement *>(imageElement.get()); 149 m_imageElement->setAttribute(styleAttr, "-webkit-user-select: none"); 150 m_imageElement->setLoadManually(true); 151 m_imageElement->setSrc(URL()); 152 153 body->appendChild(imageElement, ec); 154 155 if (!frame()->page()->settings()->shrinksStandaloneImagesToFit()) 156 return; 157 158 // Add event listeners 159 RefPtr<EventListener> listener = new ImageEventListener(this); 160 addWindowEventListener("resize", listener, false); 161 m_imageElement->addEventListener("click", listener.release(), false); 162 } 163 164 float ImageDocument::scale() const 165 { 166 IntSize imageSize = m_imageElement->cachedImage()->imageSize(); 167 IntSize windowSize = IntSize(frame()->view()->width(), frame()->view()->height()); 168 169 float widthScale = (float)windowSize.width() / imageSize.width(); 170 float heightScale = (float)windowSize.height() / imageSize.height(); 171 172 return min(widthScale, heightScale); 173 } 174 175 void ImageDocument::resizeImageToFit() 176 { 177 IntSize imageSize = m_imageElement->cachedImage()->imageSize(); 178 179 float scale = this->scale(); 180 m_imageElement->setWidth(imageSize.width() * scale); 181 m_imageElement->setHeight(imageSize.height() * scale); 182 } 183 184 void ImageDocument::imageClicked(int x, int y) 185 { 186 if (!m_imageSizeIsKnown || imageFitsInWindow()) 187 return; 188 189 m_shouldShrinkImage = !m_shouldShrinkImage; 190 191 if (m_shouldShrinkImage) 192 windowSizeChanged(); 193 else { 194 restoreImageSize(); 195 196 updateLayout(); 197 198 float scale = this->scale(); 199 200 int scrollX = x / scale - (float)frame()->view()->width() / 2; 201 int scrollY = y / scale - (float)frame()->view()->height() / 2; 202 203 frame()->view()->setContentsPos(scrollX, scrollY); 204 } 205 } 206 207 void ImageDocument::imageChanged() 208 { 209 ASSERT(m_imageElement); 210 211 if (m_imageSizeIsKnown) 212 return; 213 214 if (m_imageElement->cachedImage()->imageSize().isEmpty()) 215 return; 216 217 m_imageSizeIsKnown = true; 218 219 if (!frame()->page()->settings()->shrinksStandaloneImagesToFit()) 220 return; 221 222 // Force resizing of the image 223 windowSizeChanged(); 224 } 225 226 void ImageDocument::restoreImageSize() 227 { 228 if (!m_imageSizeIsKnown) 229 return; 230 231 m_imageElement->setWidth(m_imageElement->cachedImage()->imageSize().width()); 232 m_imageElement->setHeight(m_imageElement->cachedImage()->imageSize().height()); 233 234 m_didShrinkImage = false; 235 } 236 237 bool ImageDocument::imageFitsInWindow() const 238 { 239 IntSize imageSize = m_imageElement->cachedImage()->imageSize(); 240 IntSize windowSize = IntSize(frame()->view()->width(), frame()->view()->height()); 241 242 return imageSize.width() <= windowSize.width() && imageSize.height() <= windowSize.height(); 243 } 244 245 void ImageDocument::windowSizeChanged() 246 { 247 if (!m_imageSizeIsKnown || !m_shouldShrinkImage) 248 return; 249 250 bool fitsInWindow = imageFitsInWindow(); 251 252 if (m_didShrinkImage) { 253 // If the window has been resized so that the image fits, restore the image size 254 // otherwise update the restored image size. 255 if (fitsInWindow) 256 restoreImageSize(); 257 else 258 resizeImageToFit(); 259 } else { 260 // If the image isn't resized but needs to be, then resize it. 261 if (!fitsInWindow) { 262 resizeImageToFit(); 263 m_didShrinkImage = true; 264 } 265 } 266 } 267 268 CachedImage* ImageDocument::cachedImage() 269 { 270 if (!m_imageElement) 271 createDocumentStructure(); 272 273 return m_imageElement->cachedImage(); 274 } 275 276 void ImageEventListener::handleEvent(Event* event, bool isWindowEvent) 277 { 278 if (event->type() == resizeEvent) 279 m_doc->windowSizeChanged(); 280 else if (event->type() == clickEvent) { 281 MouseEvent* mouseEvent = static_cast<MouseEvent*>(event); 282 m_doc->imageClicked(mouseEvent->x(), mouseEvent->y()); 283 } 284 } 285 286 } -
trunk/WebCore/loader/ImageDocument.h
r21179 r21686 31 31 class DOMImplementation; 32 32 class FrameView; 33 33 class HTMLImageElement; 34 34 35 class ImageDocument : public HTMLDocument 35 36 { … … 40 41 41 42 virtual Tokenizer* createTokenizer(); 43 44 CachedImage* cachedImage(); 45 HTMLImageElement* imageElement() const { return m_imageElement; } 46 47 void windowSizeChanged(); 48 void imageChanged(); 49 void imageClicked(int x, int y); 50 private: 51 void createDocumentStructure(); 52 void resizeImageToFit(); 53 void restoreImageSize(); 54 bool imageFitsInWindow() const; 55 float scale() const; 56 57 HTMLImageElement* m_imageElement; 58 59 // Whether enough of the image has been loaded to determine its size 60 bool m_imageSizeIsKnown; 61 62 // Whether the image is shrunk to fit or not 63 bool m_didShrinkImage; 64 65 // Whether the image should be shrunk or not 66 bool m_shouldShrinkImage; 42 67 }; 43 68 -
trunk/WebCore/page/Settings.cpp
r20820 r21686 47 47 , m_usesDashboardBackwardCompatibilityMode(false) 48 48 , m_needsAcrobatFrameReloadingQuirk(false) 49 , m_shrinksStandaloneImagesToFit(true) 49 50 { 50 51 // A Frame may not have been created yet, so we initialize the AtomicString … … 224 225 } 225 226 227 void Settings::setShrinksStandaloneImagesToFit(bool shrinksStandaloneImagesToFit) 228 { 229 m_shrinksStandaloneImagesToFit = shrinksStandaloneImagesToFit; 230 } 231 226 232 } // namespace WebCore -
trunk/WebCore/page/Settings.h
r20820 r21686 118 118 bool isDOMPasteAllowed() const { return m_isDOMPasteAllowed; } 119 119 120 void setShrinksStandaloneImagesToFit(bool); 121 bool shrinksStandaloneImagesToFit() const { return m_shrinksStandaloneImagesToFit; } 122 120 123 private: 121 124 String m_defaultTextEncodingName; … … 142 145 bool m_usesDashboardBackwardCompatibilityMode : 1; 143 146 bool m_needsAcrobatFrameReloadingQuirk : 1; 144 bool m_isDOMPasteAllowed: 1; 147 bool m_isDOMPasteAllowed : 1; 148 bool m_shrinksStandaloneImagesToFit : 1; 145 149 }; 146 150
Note: See TracChangeset
for help on using the changeset viewer.