Bug 14998 - Full page zooming support
Summary: Full page zooming support
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: New Bugs (show other bugs)
Version: 523.x (Safari 3)
Hardware: All All
: P2 Normal
Assignee: Dave Hyatt
URL:
Keywords: Gtk
Depends on:
Blocks: 18281
  Show dependency treegraph
 
Reported: 2007-08-17 08:33 PDT by George Wright
Modified: 2008-04-04 08:13 PDT (History)
9 users (show)

See Also:


Attachments
Preliminary zooming support (5.01 KB, patch)
2007-08-17 08:40 PDT, George Wright
no flags Details | Formatted Diff | Diff
WebKit zooming (9.95 KB, patch)
2007-08-23 13:44 PDT, George Wright
no flags Details | Formatted Diff | Diff
Update to zooming code, bugfixes (12.54 KB, patch)
2007-08-30 05:23 PDT, George Wright
no flags Details | Formatted Diff | Diff
More bugfixes, some code cleanup (18.09 KB, patch)
2007-09-06 09:17 PDT, George Wright
no flags Details | Formatted Diff | Diff
General clean ups, bug fixed for resize events (18.83 KB, patch)
2007-09-07 07:08 PDT, George Wright
no flags Details | Formatted Diff | Diff
Add zoom functionality to GdkLauncher for testing purposes (2.17 KB, patch)
2007-09-07 07:10 PDT, George Wright
oliver: review-
Details | Formatted Diff | Diff
Small changes to conform to coding style, general tidying up (19.00 KB, patch)
2007-09-07 09:41 PDT, George Wright
oliver: review-
Details | Formatted Diff | Diff
Moved implementation from WebKit to WebCore (24.44 KB, patch)
2007-09-11 09:55 PDT, George Wright
no flags Details | Formatted Diff | Diff
Moved scaleFactor methods into Page (26.79 KB, patch)
2007-09-20 05:52 PDT, George Wright
no flags Details | Formatted Diff | Diff
Changed names from GDK to GTK, more code cleanups (26.45 KB, patch)
2007-09-27 06:42 PDT, George Wright
no flags Details | Formatted Diff | Diff
Changed Page::scaleFactor to const, fixed broken email address (26.44 KB, patch)
2007-09-27 07:07 PDT, George Wright
no flags Details | Formatted Diff | Diff
Update to reflect WebKitGtk -> WebKit name change (24.09 KB, patch)
2007-10-04 03:19 PDT, George Wright
aroben: review-
Details | Formatted Diff | Diff
Change events instead of duplicating them, various other cleanups (30.43 KB, patch)
2007-10-08 04:12 PDT, George Wright
aroben: review-
Details | Formatted Diff | Diff
Code cleanup (22.07 KB, patch)
2007-10-22 03:42 PDT, George Wright
alp: review-
Details | Formatted Diff | Diff
New approach to full page zoom (68.39 KB, patch)
2008-03-18 19:32 PDT, Dave Hyatt
hyatt: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description George Wright 2007-08-17 08:33:24 PDT
I would very much like to see full page zooming support in WebKit, such as the zooming Safari on the iPhone has.

I have started working on investigating how zooming support can be implemented in the GTK API, but it would be better if we could standardise on a method for this to be done. The GraphicsContext has a function scale(FloatSize), but calling that method alone does not result in the required behaviour for zooming - mouse events still think the geometry is as for a scale factor of 1.0.
Comment 1 George Wright 2007-08-17 08:40:48 PDT
Created attachment 16010 [details]
Preliminary zooming support

Preliminary patch submitted as a request for comments. This patch simply updates the expose event in GTK to scale the graphics context and performs coordinate transformations in the mouse/button/etc events to transform to the new scale.

Buttons are not yet scaled, but are placed at the right location on page. This seems to be GTK specific, because if the code in RenderThemeGdk.cpp in method paintButton() is replaced with simply "return true;", the fallback button rendering is the correct size.

There is a problem with invalidating rectangles in the GDK scrollview. I have narrowed this problem down to the updateContents() method in ScrollViewGdk.cpp.

The problem is how to propagate the scale factor to these classes in a sane and cross-platform way so that we can do coordinate transformations.
Comment 2 George Wright 2007-08-23 13:44:06 PDT
Created attachment 16100 [details]
WebKit zooming

An update to the last patch which fixes a scrolling issue such that only a small portion of the page re-renders when scrolled (transformations issue in ScrollView::update()). Widgets now resize according to the scale factor, but radio buttons don't seem to resize (their size is hardcoded?)

Implemented ChromeClient::scaleFactor() for GTK which returns the scale factor set in pageData. Added GraphicsContext::translateSize() method to the cairo implementation as coordinate transformations for points and distances are different.

There are still issues with invalidating rects when hovering the mouse over widgets.
Comment 3 David Kilzer (:ddkilzer) 2007-08-23 14:02:42 PDT
Thanks for the patches, George!  If you'd like them reviewed (even if it's just for preliminary feedback), please set the "review?" flag on the patch.

For future reference:  http://webkit.org/coding/contributing.html

Comment 4 George Wright 2007-08-23 14:09:05 PDT
The patches aren't intended to go into WebKit yet, hence why I've not marked them for review. I'm simply trying to get ideas and suggestions as to the best way to implement this (the patches are very rough round the edges at the moment). Thanks for your support though! 
Comment 5 David Kilzer (:ddkilzer) 2007-08-23 14:52:15 PDT
(In reply to comment #4)
> The patches aren't intended to go into WebKit yet, hence why I've not marked
> them for review. I'm simply trying to get ideas and suggestions as to the best
> way to implement this (the patches are very rough round the edges at the
> moment). Thanks for your support though! 

That's one reason to set the "review?" flag--to get ideas and suggestions.  :)

Comment 6 Holger Freyther 2007-08-24 02:06:24 PDT
Some comments on the patch itself:

+    IntSize size(rect.width(), rect.height());
+    size = i.context->translateSize(size);

=>  IntSize size = i.context->translateSize(rect.size())

+    // Is this optimal?
+    FrameView* frameView = static_cast<const FrameView*>(this);
+    Page* page = frameView->frame() ? frameView->frame()->page() : 0;
+
+    double scaleFactor = page->chrome()->client()->scaleFactor();

a) double -> float -> double? is that what we want? I think not. Even if I mentioned ChromeCLient::scaleFactor we should not use it here.
b) I wonder why the compiler allows you to do the cast. Probably because this is not const in this method but then remove const from the cast
c) if you cast in ScrollView to FrameView, either add an ASSERT(isFrameView()) or a if whatever is more appropriate
d) You might want to access the PrivateData of the WebKitGtkPage to get the scale factor. You can do so by using the Widget::containingWindow().


+static void transform_coordinates_int(GtkWidget* widget, bool inverted, int *x, int *y)
+static void transform_coordinates_double(GtkWidget* widget, bool inverted, double *x, double *y)

A small violation of the CodingStyle, You place the '*' (asterisk) at the wrong place.


+void webkit_gtk_page_set_scale_factor(WebKitGtkPage* page, double factor)
+{
+    WebKitGtkPagePrivate* pageData = WEBKIT_GTK_PAGE_GET_PRIVATE(page);
+
+    pageData->scaleFactor = factor;
+    // TODO: redraw page with new scale factor

a {ScrollView,FrameView}::update() should do the trick. It should be enough to use the FrameView of the mainFrame.


Comment 7 Holger Freyther 2007-08-24 02:25:55 PDT
(In reply to comment #2)
> Created an attachment (id=16100) [edit]
> WebKit zooming
> 
> An update to the last patch which fixes a scrolling issue such that only a
> small portion of the page re-renders when scrolled (transformations issue in
> ScrollView::update()). Widgets now resize according to the scale factor, but
> radio buttons don't seem to resize (their size is hardcoded?)

Check with a different GtkStyle/Theme, check the size and point before and after the transformation and you might want to take a look at RenderTheme and check if there is a method you might want to reimplement.


> 
> There are still issues with invalidating rects when hovering the mouse over
> widgets.

This is one of the fundamental issues with this scaling implementation. The Render Tree has its own unscaled coordinates and e.g. hovering is done using the HitTest. So there must be something in WebCore/render which is asking the ScrollView/FrameView to repaint in case of hover and we will need to translate that as well. This could be Widget::invalidateRect but this is just a guess.

This means we need to check all Render* <-> {Widget,ScrollView} relations and check if the coordinates get translated properly...
Comment 8 George Wright 2007-08-24 07:06:32 PDT
There seem to be severe performance issues with non-integral scale factors. i.e. - if scaleFactor is set to 1.2, performance is noticeably laggy, and scrolling complex pages (such as BBC news) is so slow it's unusable.

Scaling down also seems to have trouble, but I'm not sure why. The layout of the entire page is completely broken and half the page doesn't seem to be rendered.

Does anyone have any suggestions for performance improvements?
Comment 9 Holger Freyther 2007-08-24 07:29:43 PDT
One nore thing with translateSize. As there will be translateSize+translatePoint what about only translating the rect directly?
Comment 10 Holger Freyther 2007-08-24 07:33:29 PDT
(In reply to comment #8)
> There seem to be severe performance issues with non-integral scale factors.
> i.e. - if scaleFactor is set to 1.2, performance is noticeably laggy, and
> scrolling complex pages (such as BBC news) is so slow it's unusable.
> 
> Scaling down also seems to have trouble, but I'm not sure why. The layout of
> the entire page is completely broken and half the page doesn't seem to be
> rendered.
> 
> Does anyone have any suggestions for performance improvements?

No just a small suggestions on how to identify the offender.

a) tronical (Simon) did implement zooming for konqueror embedded, you might ask him for his approach back then.
b) I think it is important to either identify Gtk+, WebCore or cairo as offender. I would look into callgrind/kcallgrind and if that turns out to be too slow would go to oprofile and LinuxTracingToolkit (LTT) to find out where the time is spend. To be able to replicate your testing you might want to drive scrolling programatically by manipulating the GtkAdjustment that get set on the WebKitGtkPage.

Comment 11 George Wright 2007-08-30 05:23:18 PDT
Created attachment 16163 [details]
Update to zooming code, bugfixes

Update to my zooming code for the GTK port. Widgets now redraw correctly - invalidation works as expected. Changed to bilinear filtering for much better zooming quality.

There are still issues with certain widgets not rendering at the correct size (checkboxes, radio buttons..). These may have to be scaled.

Scrolling performance is still not ideal - this is possibly due to the fact that the GTK port currently re-renders the entire viewport when scrolling which is not optimal. I shall look into implementing double buffering and blitting the contents of the window when scrolling to save on rendering operations.

Scroll bars are currently not placed in the right place when there is a page with multiple frames, and each individual frame is scrollable.
Comment 12 George Wright 2007-09-06 09:17:17 PDT
Created attachment 16208 [details]
More bugfixes, some code cleanup

Scrolling should now work in all cases and scroll bars placed correctly, even in pages with multiple frames. Text kerning is fixed, but using a workaround for a possible cairo bug. Hinting can not be disabled completely as this introduces a regression which causes some pages to not render at all.

Scaling now uses bilinear filtering instead of nearest neighbour filtering as it looks a lot better.

Added a ChangeLog entry.
Comment 13 George Wright 2007-09-07 07:08:38 PDT
Created attachment 16216 [details]
General clean ups, bug fixed for resize events

I am now casting to an int wherever I transform a size by multiplying it with a scale factor.

Bug fixed which didn't resize the window properly when webkit_gtk_page_set_scale_factor was called, thus resulting in a resized page in a viewport that was the wrong size.

Some artifacting seen due to antialiasing so increased the expose event handler's cliprect to be 2 pixels larger all round.

Added an API method to get the current scale factor.
Comment 14 George Wright 2007-09-07 07:10:47 PDT
Created attachment 16217 [details]
Add zoom functionality to GdkLauncher for testing purposes

A small patch to add zoom in/zoom out menu entries to GdkLauncher which change the scale factor by 120% each time.
Comment 15 George Wright 2007-09-07 09:41:00 PDT
Created attachment 16218 [details]
Small changes to conform to coding style, general tidying up

Changed C-style casts to C++ static_casts. Added a link to a Cairo ML post about the font rendering issue. Replaced translatePoint with translateRect and update the widget rendering accordingly.
Comment 16 Oliver Hunt 2007-09-07 12:52:18 PDT
Comment on attachment 16217 [details]
Add zoom functionality to GdkLauncher for testing purposes

style issues:
+    webkit_gtk_page_set_scale_factor(gPage, scaleFactor * 1.2);
..
+    webkit_gtk_page_set_scale_factor(gPage, scaleFactor / 1.2);

However i'd prefer a integer representing the scale level, which you then modified, eg:
+static void menuMainZoomInCallback(gpointer)
+{
+    if (scaleFactor < 10)
+        scaleFactor++;
+    webkit_gtk_page_set_scale_factor(gPage, scaleFactor * whatever);
+}
+
+static void menuMainZoomOutCallback(gpointer)
+{
+    if (scaleFactor > 0)
+        scaleFactor--;
+    webkit_gtk_page_set_scale_factor(gPage, scaleFactor * whatever);
+}

Which would mean that you wouldn't get cumulative rounding error over time.
Comment 17 Oliver Hunt 2007-09-07 13:08:31 PDT
Comment on attachment 16218 [details]
Small changes to conform to coding style, general tidying up

Scaling the render region outside of the engine itself can cause also of badness, especially with hit testing, region invalidation and what not.

I think you'd benefit from matching the WebView API from mac.

– canMakeTextLarger  
– makeTextLarger:  
– canMakeTextSmaller  
– makeTextSmaller:

Which would be on gtk WebView equivalent -- the Mac impl is kind of messy, look at the windows ones as they do much less icky objc-fu.

makeTextSmaller/Larger are designed to allow buttons to be hooked up directly -- i think that would mean you want them to be "slots"/"sockets" or whatever the gtk name for something like that is.
Comment 18 George Wright 2007-09-07 14:57:38 PDT
The text resizing corresponds to the setZoomLevel and zoomLevel functions in the Frame class as far as I can tell, which we are not implementing here. As for the hit tests, I've accounted for all of those in this GTK implementation but I can see where your concerns are as it's not done in WebCore and so other ports won't benefit from this.

I'll have a look at moving the code from WebKit/GTK into WebCore. There's already a scale() function in the GraphicsContext class so I think that's probably the best way to propagate the scale factor around WebCore, and then add the code to perform the coordinate transformations directly in ScrollView/Render*/etc. Now that I basically know which hit tests are required this hopefully won't take long, then with any luck the only WebKit change required will be to add an API method which calls GraphicsContext::scale().
Comment 19 George Wright 2007-09-11 09:55:19 PDT
Created attachment 16259 [details]
Moved implementation from WebKit to WebCore

Now rounding to scaled pixels for cairo clipping to improve performance. Coordinate transformations moved from WebKit to WebCore and implemented generically in EventHandler so that all ports can benefit.
Comment 20 George Wright 2007-09-20 05:52:37 PDT
Created attachment 16332 [details]
Moved scaleFactor methods into Page

This patch moves the scaleFactor methods from ScrollView into Page. This is because the scale factor is common to all frames (and hence ScrollView objects) in a Page, and setting the scale factor in ScrollView does not make it easy to recurse changes into child ScrollViews in pages with multiple frames, whereas keeping the scale factor in Page makes more sense as it can be accessed by all ScrollView objects on that page.
Comment 21 Holger Freyther 2007-09-25 09:44:57 PDT
(In reply to comment #20)
> Created an attachment (id=16332) [edit]
> Moved scaleFactor methods into Page

Page::scaleFactor() const { ... } would probably be better (add a const). Any why do you make ScrollView::scaleFactor port specific? The Gtk+ implementation looks pretty generic to me.
Comment 22 George Wright 2007-09-27 06:42:00 PDT
Created attachment 16412 [details]
Changed names from GDK to GTK, more code cleanups

This is a patch to reflect the recent renaming of the GTK port from GDK to GTK throughout.

The platform-specific methods for scaleFactor have been removed and this shouldn't break any other builds any more. 

I have reverted back to CAIRO_FILTER_NEAREST as there is ugly artifacting at the edge of tiled images with bilinear filtering.
Comment 23 George Wright 2007-09-27 07:07:09 PDT
Created attachment 16413 [details]
Changed Page::scaleFactor to const, fixed broken email address

Page::scaleFactor is now const. Fixed broken email address field in ChangeLog.
Comment 24 Darin Adler 2007-09-27 15:31:18 PDT
Comment on attachment 16413 [details]
Changed Page::scaleFactor to const, fixed broken email address

I think the naming of variables is a little weak. For example "event" is the event without scaling applied, and "mouseEvent" is the event with scaling applied. The names should make more clearly what's going on. In particular, what's happening is that we're converting the x/y coordinates from viewport coordinates to scaled viewport coordinates. But I also think it would be more logical to do the scaling when converting from viewport coordinates to document coordinates.

I also think it's a little weak to make an entire copy of the event in cases like this -- since the only thing affected is the x/y coordinates. This will cause a disconnect between the original event object and the new one; for example the scaled mouse event won't have the correct event number (on Macintosh). We should come up with a better design that separates the scaled X/Y from the rest of the event or allows you to change the X/Y in an event or something along those lines.

It's bad to override a non-virtual function FrameView::resize -- for one thing there are two overloads of resize and one takes an IntSize. For another it's almost never a good idea to override a non-virtual function. I'd like to see a clearer set of rules about which parameters are which kinds of coordinates.

The Page::setScaleFactor function should do more than just set the new scale factor value. Like Frame::setZoomFactor (that function has a terrible name and place!) it should trigger the appropriate layout and painting.

The patch seems to have some Cairo things not directly related to the arbitrary zooming; lets land those separately.

High level code should almost never be explicitly multiplying by the scale factor. The correct primitives are to change coordinates from document space to viewport space. So PlatformScrollbar::geometryChanged should not need to multiply by the scale factor. I think contentsToWindow might be the function we want to modify, or something along those lines.

One problem I see is that on Mac we have arbitrary transforms on WebView, but currently they don't work properly; if I was doing a patch, I'd do the cross-platform code that handles things like mouse events in a way that could work for that as well. The code should be based on the concept of an arbitrary transform even if what's stored is simply a scale factor.
Comment 25 George Wright 2007-10-04 03:19:34 PDT
Created attachment 16529 [details]
Update to reflect WebKitGtk -> WebKit name change

Just a quick update to rename all calls to the WebKit GTK public API to the new names.
Comment 26 Holger Freyther 2007-10-06 02:40:19 PDT
Comment on attachment 16529 [details]
Update to reflect WebKitGtk -> WebKit name change

George forgot to ask for review...
Comment 27 Adam Roben (:aroben) 2007-10-07 16:15:04 PDT
Comment on attachment 16529 [details]
Update to reflect WebKitGtk -> WebKit name change

-        IntPoint translatePoint(const IntPoint&) const;
+        IntRect translateRect(const IntRect&) const;

I don't think translateRect is a good name for this method, since it both translates and scales. A better name might be transformRect.

+    WebKitPage* page = WEBKIT_PAGE(containingWindow());
+    WebKitPagePrivate* pageData = WEBKIT_PAGE_GET_PRIVATE(page);

This code (in ScrollViewGtk.cpp) is unused. We also should not be using WebKit types within WebCore.

+    double scaleFactor = frameView->frame()->page()->scaleFactor();

There are a number of places where the result of Frame::page() is being used without a null-check. This is in general an unsafe thing to do.

r- given the above and Darin's comments. I think Darin gave some really good suggestions about how to improve the design of this feature.
Comment 28 George Wright 2007-10-08 04:12:47 PDT
Created attachment 16587 [details]
Change events instead of duplicating them, various other cleanups

Added a function Platform{Mouse,Wheel}Event::scale(double) which transforms its X/Y coordinates to accommodate the scale factor.

Renamed m_{width,height} to {width,height}.

Unsure as to how to proceed re. Darin's comments about overloading Widget::resize; does anyone have any comments on how to do this sanely?
Comment 29 Adam Roben (:aroben) 2007-10-08 11:42:10 PDT
Comment on attachment 16587 [details]
Change events instead of duplicating them, various other cleanups

+    const_cast<PlatformMouseEvent&>(event).scale(scaleFactor());

This feels ugly to me. If it's not possible for the scale factor to change while an event is being handled (is it?), we could generate the scaled position in the Platform*Event constructors. If it turns out that most users of the Platform*Event types really want to be dealing with the scaled coordinates, we could even make Platform*Event::pos() return the scaled position, and come up with a new method to return the unscaled one (I like Darin's idea of coming up with better names for these than just [un]scaled).

I think you should revert the variable renames in EventHandler.cpp to make the diff smaller.

I also agree with Darin that the miscellaneous Cairo changes should be split into a separate bug/patch.

Have you thought about Darin's comments re: not multiplying by the scale factor in high-level code?
Comment 30 George Wright 2007-10-10 02:58:24 PDT
(In reply to comment #29)
> (From update of attachment 16587 [details] [edit])
> +    const_cast<PlatformMouseEvent&>(event).scale(scaleFactor());
> 
> This feels ugly to me. If it's not possible for the scale factor to change
> while an event is being handled (is it?), we could generate the scaled position
> in the Platform*Event constructors. If it turns out that most users of the
> Platform*Event types really want to be dealing with the scaled coordinates, we
> could even make Platform*Event::pos() return the scaled position, and come up
> with a new method to return the unscaled one (I like Darin's idea of coming up
> with better names for these than just [un]scaled).
> 
> I think you should revert the variable renames in EventHandler.cpp to make the
> diff smaller.

The problem with that is that the Platform*Event constructors don't have access to the Page object and so can't get the current scale factor, unless I'm missing something fantastically obvious.

> I also agree with Darin that the miscellaneous Cairo changes should be split
> into a separate bug/patch.

To be honest, those Cairo changes are more of a hack than anything; ideally we'd want to use EXTEND_PAD but that's not currently implemented in Cairo as far as I know.

> Have you thought about Darin's comments re: not multiplying by the scale factor
> in high-level code?

Yes - I'll take a look at that when I have some time.
Comment 31 Adam Roben (:aroben) 2007-10-10 08:09:24 PDT
(In reply to comment #30)
> (In reply to comment #29)
> > (From update of attachment 16587 [details] [edit] [edit])
> > +    const_cast<PlatformMouseEvent&>(event).scale(scaleFactor());
> > 
> > This feels ugly to me. If it's not possible for the scale factor to change
> > while an event is being handled (is it?), we could generate the scaled position
> > in the Platform*Event constructors. If it turns out that most users of the
> > Platform*Event types really want to be dealing with the scaled coordinates, we
> > could even make Platform*Event::pos() return the scaled position, and come up
> > with a new method to return the unscaled one (I like Darin's idea of coming up
> > with better names for these than just [un]scaled).
> 
> The problem with that is that the Platform*Event constructors don't have access
> to the Page object and so can't get the current scale factor, unless I'm
> missing something fantastically obvious.

Couldn't you pass in the scale factor as an argument to the constructors?
Comment 32 George Wright 2007-10-22 03:36:12 PDT
(In reply to comment #31)
> Couldn't you pass in the scale factor as an argument to the constructors?

The problem with that is that the events are generated in WebKit (specifically webkitgtkpage.cpp in the case of the GTK port), and I feel this code should be in WebCore rather than WebKit (and the current implementation is port-independent).
Comment 33 George Wright 2007-10-22 03:42:28 PDT
Created attachment 16790 [details]
Code cleanup

Just a quick update to remove all the event renaming in EventHandler.
Comment 34 Alp Toker 2007-10-26 19:38:26 PDT
So, this approach is partly obsoleted by the new CSS transform support, though it will need more work to support transformed widgets.

[03:35] <dhyatt> alp: that you could implement zooming by just scaling the <html> around an origin of 0,0
Comment 35 George Wright 2007-10-27 03:55:54 PDT
I think that conceptually the two implementations are different. The transformations functionality is to allow the web designer to implement transformations for parts of the webpage, whereas the intention of my scaling support is to allow it to be more accessible to people; that is, to use webkit on high DPI screens or to scale the page to make it easier to read.

Thus, I think there should still be an API for setting the page scale factor, whether it uses the same code as the transformations code or not.
Comment 36 Alp Toker 2007-11-08 21:54:14 PST
Comment on attachment 16790 [details]
Code cleanup

Hey, am going to r- this to clear it from the request queue since I think we've discussed the new approach involving CSS transforms. George, I think there is still some mileage in this patch but we should move forward together on a simpler solution.
Comment 37 Alp Toker 2007-11-30 04:31:37 PST
Simple (untested) way one might do this using CSS, suggestions for a way to achieve this on WebKitPage rather than WebKitFrame or without modifying the DOM would be welcome):

void webkit_frame_set_scale(WebKitFrame* frame, double scale)
{
    g_return_if_fail(WEBKIT_IS_FRAME(frame));

    WebKitFramePrivate* frameData = WEBKIT_FRAME_GET_PRIVATE(frame);
    Frame* wframe = frameData->frame;
    Document* document = wframe->document();
    HTMLElement* root = reinterpret_cast<HTMLElement*>(document->documentElement());
    RenderObject* renderer = root->renderer();
    RenderStyle* style = renderer->style();
    TransformOperations ops;
    ScaleTransformOperation* scaleOp = new ScaleTransformOperation(scale, scale);
    ops.append(scaleOp);
    style->setTransform(ops);
    renderer->setStyle(style);
}
Comment 38 Dave Hyatt 2008-01-25 12:03:14 PST
The CSS approach is good.  Here are some comments:

(1) You basically want a Setting (like text zoom but, e.g., pageZoom). 
(2) The Document reads the setting and sets a scale transform on the RenderView's style.  It only needs to do this for the *outermost* document (so only if ownerElement() is 0).
(3) In order to be placed at the upper left, you have to setTransformOrigin to (0,0).
(4) Widgets won't work right initially, but that's ok.  An initial patch doesn't need to deal with widgets (and we have a bug filed on widgets not working with transforms already).
(5) To make the scrollbars adapt properly you need to modify lowest/rightmost/leftmostPosition.  However they only have to adapt if they aren't also being transformed so be aware of that.

Comment 39 Dave Hyatt 2008-03-18 19:32:07 PDT
Created attachment 19878 [details]
New approach to full page zoom
Comment 40 Dave Hyatt 2008-03-21 22:18:36 PDT
Comment on attachment 19878 [details]
New approach to full page zoom

olliej reviewed.
Comment 41 Dave Hyatt 2008-03-21 22:18:47 PDT
Fixed.