Bug 26425

Summary: Small Refactoring to Consolidate Common GDI Calls
Product: WebKit Reporter: Brent Fulgham <bfulgham>
Component: WebKit Misc.Assignee: Brent Fulgham <bfulgham>
Status: RESOLVED FIXED    
Severity: Normal CC: aroben, sfalken
Priority: P2    
Version: 528+ (Nightly build)   
Hardware: PC   
OS: Windows XP   
Attachments:
Description Flags
Rev 1.
eric: review-
Rev. 2.
none
Rev 3
aroben: review-
Part 1 (XFORM operator)
aroben: review-
Part 2: (BitmapInfo structure)
aroben: review-
Part 3: (Use BitmapInfo Structure)
none
Part 1: BitmapInfo Refactoring
aroben: review+
Part 2: (Refactor XFORM)
aroben: review+
Part 3: (Move common logic to parent)
eric: review+
Part 4: (Final cleanups)
eric: review+
Part 5: (Some missed cleanups) levin: review+

Brent Fulgham
Reported 2009-06-15 17:26:11 PDT
There are a number of places where BITMAPINFO structures and XFORM structures are created. These are almost always the same, and seem like a good opportunity to abstract these structure filling routines to be shared between the various Windows ports. This patch adds a new GDIUtilities.h/GDIUtilities.cpp file that contains implementations of routines to: 1. Construct the typical BITMAPINFO structure we use in various operations. 2. Clear the data in a BITMAP structure. 3. Construct a Windows XFORM object from the input matrix components. After this patch, several methods in GraphicsContextCGWin and GraphicsContextCairoWin can be pushed up to GraphicsContextWin.
Attachments
Rev 1. (15.40 KB, patch)
2009-06-15 17:35 PDT, Brent Fulgham
eric: review-
Rev. 2. (19.92 KB, patch)
2009-06-15 18:12 PDT, Brent Fulgham
no flags
Rev 3 (31.38 KB, patch)
2009-06-17 15:39 PDT, Brent Fulgham
aroben: review-
Part 1 (XFORM operator) (3.89 KB, patch)
2009-06-17 16:04 PDT, Brent Fulgham
aroben: review-
Part 2: (BitmapInfo structure) (5.84 KB, patch)
2009-06-17 16:14 PDT, Brent Fulgham
aroben: review-
Part 3: (Use BitmapInfo Structure) (9.64 KB, patch)
2009-06-17 16:35 PDT, Brent Fulgham
no flags
Part 1: BitmapInfo Refactoring (14.89 KB, patch)
2009-06-17 16:41 PDT, Brent Fulgham
aroben: review+
Part 2: (Refactor XFORM) (9.46 KB, patch)
2009-06-17 16:56 PDT, Brent Fulgham
aroben: review+
Part 3: (Move common logic to parent) (10.62 KB, patch)
2009-06-17 21:19 PDT, Brent Fulgham
eric: review+
Part 4: (Final cleanups) (6.18 KB, patch)
2009-06-18 14:07 PDT, Brent Fulgham
eric: review+
Part 5: (Some missed cleanups) (7.53 KB, patch)
2009-06-18 17:31 PDT, Brent Fulgham
levin: review+
Brent Fulgham
Comment 1 2009-06-15 17:35:21 PDT
Eric Seidel (no email)
Comment 2 2009-06-15 17:38:03 PDT
Looks great to me. The patch is missing the new files, and Adam and Steve are the people you should really ask about windows changes.
Eric Seidel (no email)
Comment 3 2009-06-15 17:38:19 PDT
Comment on attachment 31320 [details] Rev 1. Missing the added files.
Brent Fulgham
Comment 4 2009-06-15 18:12:59 PDT
Created attachment 31325 [details] Rev. 2. Show missing (new) files.
Adam Roben (:aroben)
Comment 5 2009-06-16 10:42:32 PDT
Comment on attachment 31325 [details] Rev. 2. > + #ifndef GdiUtilities_h This should be GDIUtilities_h. We always match the case of the file name. In general we've tried to resist adding *Utilities files, partly because they can become a catch-all. So I've been trying to think about how we could remove the need for such a file here. > + XFORM makeXFORM(float, float, float, float, float, float); I think it would be better to add an operator XFORM() to the TransformationMatrix class instead of adding the makeXFORM function. Then we can change the existing code to use TransformationMatrix::translate to convert the rect into a matrix, and convert that to an XFORM. Does that make sense? > + BITMAPINFO bitmapInfoForSize(const IntSize&, bool invertHeight = false); Boolean parameters make it hard to read code, and optional boolean parameters make it really easy to make mistakes when the function signature changes. You could replace the optional boolean with a required two-member enum, like this: enum BitmapOrientation { TopDown, BottomUp }; BITMAPINFO bitmapInfoForSize(const IntSize&, BitmapOrientation). Or you could just require the caller to negate the height themselves. Another option, which would allow moving this function out of GDIUtilities (and get us a step closer to removing that file altogether), would be to create a WebCore::BitmapInfo struct that derives from BITMAPINFO. Something like: struct BitmapInfo : public BITMAPINFO { static BitmapInfo create(const IntSize&); static BitmapInfo createBottomUp(const IntSize&); }; > + void fillWithClearColor(HBITMAP); I'm not sure what to do with this one.
Brent Fulgham
Comment 6 2009-06-16 11:50:48 PDT
(In reply to comment #5) > In general we've tried to resist adding *Utilities files, partly because they > can become a catch-all. So I've been trying to think about how we could remove > the need for such a file here. Okay > > + XFORM makeXFORM(float, float, float, float, float, float); > > I think it would be better to add an operator XFORM() to the > TransformationMatrix class instead of adding the makeXFORM function. Then we > can change the existing code to use TransformationMatrix::translate to convert > the rect into a matrix, and convert that to an XFORM. Does that make sense? Yes. I can do that. > > + BITMAPINFO bitmapInfoForSize(const IntSize&, bool invertHeight = false); > Another option, which would allow moving this function out of GDIUtilities (and > get us a step closer to removing that file altogether), would be to create a > WebCore::BitmapInfo struct that derives from BITMAPINFO. Something like: > > struct BitmapInfo : public BITMAPINFO { > static BitmapInfo create(const IntSize&); > static BitmapInfo createBottomUp(const IntSize&); > }; That's a good idea. Should this be in its own set of files, or is there someplace else where this would make sense? > > + void fillWithClearColor(HBITMAP); > > I'm not sure what to do with this one. The only thing that uses this is GraphicsContextWinXXXX, so I can just make it a method of the class and put it there.
Adam Roben (:aroben)
Comment 7 2009-06-16 14:43:57 PDT
(In reply to comment #6) > (In reply to comment #5) > > > + BITMAPINFO bitmapInfoForSize(const IntSize&, bool invertHeight = false); > > Another option, which would allow moving this function out of GDIUtilities (and > > get us a step closer to removing that file altogether), would be to create a > > WebCore::BitmapInfo struct that derives from BITMAPINFO. Something like: > > > > struct BitmapInfo : public BITMAPINFO { > > static BitmapInfo create(const IntSize&); > > static BitmapInfo createBottomUp(const IntSize&); > > }; > > That's a good idea. Should this be in its own set of files, or is there > someplace else where this would make sense? I think having its own files would be best. > > > + void fillWithClearColor(HBITMAP); > > > > I'm not sure what to do with this one. > > The only thing that uses this is GraphicsContextWinXXXX, so I can just make it > a method of the class and put it there. Adding a new function to GraphicsContext.h seems a little ugly for this platform-specific function, especially since the function doesn't involve the GraphicsContext at all. It looks like the only caller to fillWithClearColor is getWindowsContext. Can we do some refactoring to share that implementation, so that we don't need to find a way to share just this one function?
Brent Fulgham
Comment 8 2009-06-17 15:39:45 PDT
Created attachment 31453 [details] Rev 3 Revised per Adam Roben's comments.
Adam Roben (:aroben)
Comment 9 2009-06-17 15:44:26 PDT
Comment on attachment 31453 [details] Rev 3 This is looking great. Since the 4 changes are each pretty self-contained, it would be much better to get them reviewed and landed as separate patches. I also think the BitmapInfo functions should return a WebCore::BitmapInfo, not a BITMAPINFO. r- so that these changes can be split up. Thanks for the great work!
Brent Fulgham
Comment 10 2009-06-17 16:04:46 PDT
Created attachment 31456 [details] Part 1 (XFORM operator) Add new XFORM operator to TransformationMatrix
Brent Fulgham
Comment 11 2009-06-17 16:14:14 PDT
Created attachment 31457 [details] Part 2: (BitmapInfo structure) This patch adds the BitmapInfo structure for later use in some refactoring.
Adam Roben (:aroben)
Comment 12 2009-06-17 16:17:37 PDT
Comment on attachment 31456 [details] Part 1 (XFORM operator) I don't think there's value in a patch that only adds the casting operator but doesn't use it. Can you put the code that uses it in this patch, too? Sorry for being unclear earlier.
Adam Roben (:aroben)
Comment 13 2009-06-17 16:18:00 PDT
Comment on attachment 31457 [details] Part 2: (BitmapInfo structure) Again, please put the code that uses the new functions in this patch. Sorry for being unclear.
Brent Fulgham
Comment 14 2009-06-17 16:35:17 PDT
Created attachment 31463 [details] Part 3: (Use BitmapInfo Structure) Depends on Patch #2. Use BitmapInfo structure instead of manual structure assembly.
Brent Fulgham
Comment 15 2009-06-17 16:41:50 PDT
Created attachment 31465 [details] Part 1: BitmapInfo Refactoring Add a new BitmapInfo structure and use to refactor some duplicated code
Adam Roben (:aroben)
Comment 16 2009-06-17 16:45:30 PDT
Comment on attachment 31465 [details] Part 1: BitmapInfo Refactoring > +++ WebCore/ChangeLog (working copy) > @@ -1,3 +1,31 @@ > +2009-06-17 Brent Fulgham <bfulgham@webkit.org> > + > + Reviewed by NOBODY (OOPS!). > + > + Refactor a few common routines in the various Windows ports > + and reduce some duplicated code. > + > + Refactor use of BITMAPINFO for the new BitmapInfo structure. You should mention the Bugzilla URL in your ChangeLog. > + BITMAPINFO bitmapInfo = BitmapInfo::create(dstRect.size()); Might as well use BitmapInfo here, too. You could give BitmapInfo a constructor that initialized bmiHeader.biSize correctly and everything else to 0. That would follow the way ATL's C++ wrappers work. Or you could leave it like you have it now. r=me
Brent Fulgham
Comment 17 2009-06-17 16:56:46 PDT
Created attachment 31467 [details] Part 2: (Refactor XFORM) Add new XFORM casting operator to TransformationMatrix, and use it to remove some duplicated code. Push the concatCTM up from the CG- and Cairo-specific files into the generic GraphicsContextWin file.
Brent Fulgham
Comment 18 2009-06-17 17:34:01 PDT
Adam Roben (:aroben)
Comment 19 2009-06-17 17:35:28 PDT
Comment on attachment 31467 [details] Part 2: (Refactor XFORM) > // Apply a translation to our context so that the drawing done will be at (0,0) of the bitmap. > - XFORM xform; > - xform.eM11 = 1.0f; > - xform.eM12 = 0.0f; > - xform.eM21 = 0.0f; > - xform.eM22 = 1.0f; > - xform.eDx = -dstRect.x(); > - xform.eDy = -dstRect.y(); > + TransformationMatrix translate(1.0f, 0.0f, 0.0f, 1.0f, -dstRect.x(), -dstRect.y()); > + XFORM xform = translate; Maybe this would be better as: XFORM xform = TransformationMatrix().translate(-dstRect.x(), -dstRect.y()); > - XFORM xform; > - xform.eM11 = size.width(); > - xform.eM12 = 0.0f; > - xform.eM21 = 0.0f; > - xform.eM22 = size.height(); > - xform.eDx = 0.0f; > - xform.eDy = 0.0f; > + > + TransformationMatrix scale(size.width(), 0.0f, 0.0f, size.height(), 0.0f, 0.0f); > + > + XFORM xform = scale; Maybe this would be better as: XFORM xform = TransformationMatrix().scale(size.width(), size.height()); > - XFORM xform; > - xform.eM11 = cosAngle; > - xform.eM12 = -sinAngle; > - xform.eM21 = sinAngle; > - xform.eM22 = cosAngle; > - xform.eDx = 0.0f; > - xform.eDy = 0.0f; > + > + TransformationMatrix rotate(cosAngle, -sinAngle, sinAngle, cosAngle, 0.0f, 0.0f); > + > + XFORM xform = rotate; You could probably use TransformationMatrix::rotate() here, but I don't know the exactly incantation (probably just TransformationMatrix().rotate(degreesAngle)). ...and so on for the other cases. r=me
Brent Fulgham
Comment 20 2009-06-17 21:19:21 PDT
Created attachment 31486 [details] Part 3: (Move common logic to parent) Add new 'flush' method to allow more common logic to be pushed to the parent file.
Eric Seidel (no email)
Comment 21 2009-06-18 13:42:45 PDT
Comment on attachment 31486 [details] Part 3: (Move common logic to parent) Assuming you're sure that the two getWindowsContext implementations are identical, than this looks great! r=me
Brent Fulgham
Comment 22 2009-06-18 13:49:43 PDT
Brent Fulgham
Comment 23 2009-06-18 13:51:10 PDT
Brent Fulgham
Comment 24 2009-06-18 14:07:28 PDT
Created attachment 31507 [details] Part 4: (Final cleanups) 1. Move WinBitmap up so both ports can use it. 2. Use more concise TransformationMatrix syntax as suggested by Adam Roben in his earlier review.
Eric Seidel (no email)
Comment 25 2009-06-18 14:09:49 PDT
Comment on attachment 31507 [details] Part 4: (Final cleanups) LGTM.
Brent Fulgham
Comment 26 2009-06-18 17:31:28 PDT
Created attachment 31522 [details] Part 5: (Some missed cleanups) A handful of changes where the BitmapInfo struct can remove duplicated code.
David Levin
Comment 27 2009-06-18 18:12:47 PDT
Assigned to bfulgham to make it clear who is landing it.
Brent Fulgham
Comment 28 2009-06-18 20:49:19 PDT
Note You need to log in before you can comment on or make changes to this bug.