My blog has been moved to ariya.ofilabs.com.

Wednesday, July 30, 2008

Be my mirror, my sword and shield

The real blog title should be: experimental live tab (thumbnail) preview in Arora.

The nice thing about hacking on WebKit is, whenever you feel you want to experiment with some whacky web browser features, you can just go ahead and implement it. The code base is clean and easy to understand. For example, I always wonder how difficult it is to have a tab thumbnail preview like in Opera, where you hover the cursor on a tab and it displays the preview of the web page in that tab. This makes it easy for you to work with dozens of tabs (I know someone in Trolltech who opens at least 30 tabs in a browser :-), because often you can have a glance of the tab before really switch to that tab.

Today [1] I decided to give it a try, of course with QtWebKit. The victim is Arora, the famous lightweight QtWebKit-based web browser. Giving it a thought, there are surely million ways to do it, from QPainter redirection, grabWidget() abuse, Widgets-on-Canvas with GraphicsView, scaled painting even to a GLWidget, you name it. As a starting point, I picked the simplest one [2]: ask the web view to render to a pixmap and scale the pixmap. After an hour or so, I got to put Arora on par with Opera, in terms of tab thumbnail preview [3].

However, the fun just starts now. Remember video with CSS reflection and HTML 5 video support? If you open a tab and plays a video there, then you switch to another tab, then hover the cursor on the previous tab, you can see that the preview is live! [4] The video even plays in that tiny little window.

Since it is impossible to show this live preview feature in a completely static screenshot, I made a 133-second screencast and put it on YouTube. See the video or watch it here:

As you can see, basically I opened three tabs: Google (0:04), a web page that plays Transformer trailer video (0:09), and another page that plays the same trailer but with added reflection effect (0:24). Then I switched back to the Google page (0:34) and placed the mouse cursor on the trailer tab (0:38). There you can see the minified trailer running nicely. Whacky? You bet :-)

There is a big room for improvement, though. For starter, I just did a hack and repainted the preview at 10 fps even though nothing has been changed in the web page (e.g. the page contains no video or animation). This needs to be optimized, say by finding out a way to update only when it is absolutely necessary. Also, the preview scaling could be better, maybe using a QGLWidget for the preview viewport so the graphics card does the scaling for use. Once real full-page zoom is landed for QtWebKit, it is also interesting to explore it for painting the preview. I'm open for more ideas, especially tricks that can push the performance.

[1] After few days only focusing on bug fixing and other usual stuff. Yes, even QtWebKit in Qt 4.4.2 will receive some love and a bunch of bug fixes.
[2] The method of course can be improved later on.
[3] The code can be found in my cloned Arora repository, under the live-preview branch.
[4] Quite a coincidence, but the radio just plays I used to roll the dice, ..... But I reckon you assume that already.

Wednesday, July 16, 2008

vim: lightning fast navigation in a large software project

Love vim but need to work with a large software project that spans a dozen subdirectories and a bazillion source files? There are plenty of solutions, vim scripts or external tools, for this particular problem. Here is one that I've used for years: using the marvelous project script.

It comprises one .vim file (the script) and .txt file (the documentation), thus dead easy to install. After that, just launch vim using: vim +Project (replace vim with gvim if you favor the GUI version), the side pane will be visible. There is where the project tree will be displayed.

For a quick start, type \C and you will be prompted to answer 4 questions, as the example below (my answers are in bold)

Enter the Name of the Entry: KOffice
Enter the Absolute Directory to Load:/home/ariya/koffice/source
Enter the CD parameter:
Enter the File Filter: *.cpp *.h *.c

which, as you might guess, create an entry with the given name from all C/C++ headers and sources from the specified directory. Wait a few seconds (or minutes, depending on the project size) for the script to scan files in your disk, at last it will show the tree (as in the screenshot above) in the project window.

You can, of course, add as many entries as you want.

Note: for optimal usage, do not forget to put this on your .vimrc file:

:let g:proj_flags="imstvcg"

For details on the meaning, see the script documentation.

Navigating the project tree is easy, if you are familiar with the vim folding. In principle, use zo and zc to open and close the fold right where the cursor is located, or zO and zC to apply it recursively, i.e. for the whole entry.

How to open a file? Just place a cursor in a file name and press Enter. Since the project window is just a normal window, switching back and forth between the project window and main editing window is as easy as Ctrl+W w. Or you can use F12 to quickly show and hide the project pane. In addition, pressing Space toggle the wide and small version of project pane.

Some more tricks. Because the project window is just a normal vim window, use the blazing fast incremental search (along with n or N) to spot the file that you want. It even does allow you to jump between different matches quickly. Again, if the project window is too narrow, hit Space to make it wider and another Space will return the width back to normal. If you press Enter on a filename to open it, a wide project window is toggled to the usual width automagically. Master this technique and you will open any file you need in an instant.

Because I love tabbed editing, I also have this in my .vimrc:

:map <C-T> <Esc>:tabnew<CR>

so that Ctrl+T opens a new empty tab. Wherever I am, I can open KSpread's Cell.cpp (to have a quick look, hence in a new tab) as fast as hitting Ctrl+T, F12, /Cell.cpp, Enter. Try to beat that.

But that is not all. You might ask: what's the use of a big file list if I don't know which file I need to open? Right, because everyone (and his dog) just needs grep. Use \G (which will use vimgrep) and type in your search string. After a while, all the matches are listed in another small window. Choose one that you want and hit Enter, all the magic ensures that the corresponding file will be opened and the cursor is right located in the matched line.

For more features, e.g. rescan the files from disk, adjust the pane width, execute a command on a file, non-global project tree, etc., refer to the script documentation.

Untap the potential of this wonderful vim script and a 3000-files project is not a burden anymore!

Sunday, July 13, 2008

from SDL to Qt: the underwater effect

Doing a real underwater after effect would involve creating a believable water caustics plus some vertex shader incantations, both are far away from my expertise and it would even have taken more than an hour I would like to spend on the rainy Sunday morning preparing an example for this week's Graphics Dojo corner. Instead, I just cheated and ported my previous SDL version of Quake-like underwater effect to use QImage, and that became the example. Since this is an animation effect, the still photo below could not really depict the idea. So, just grab the code, build it, drag-and-drop your favorite photo and stare at the result for few seconds.

Qt for doing underwater effect

Lucky to have been where I have been

Bakso (Indonesian meatballs)

This is Indonesian-style meatballs (but made from lamb instead of beef) served with noodles, soy sauce, chilli sauce and fried onions. It involved mixing mashed lamb with tapioca flour, egg white, garlic, salt, pepper, other herbs to taste and then boiling in hot water.

Saturday, July 05, 2008

dojo this week: HSV pie

Update: Fabian Jakobs has ported the Qt/C++ code to HTML Canvas and JavaScript, runnable inside a web browser.

I was having headache fiddling with some fragment programs when Helder (of SpeedCrunch fame) asked me an innocent question that eventually triggered me to write the Graphics Dojo example for this week: rendering the well-known HSV cylinder in 3-D. At first, I thought using a fragment program is the perfect solution, but considering that we are Trolls, let us write a pure Qt solution that works everywhere. So check out the code!

HSV Pie

Unfortunately, in its current state, the code is not really optimized for (near) real-time rendering. If it would have been fast enough (which I guess not really feasible with a non-OpenGL solution), we could have used it for a fancy color picker. Why use a 2-D color picker/dialog when you can have a 3-D one? I'm sure once the 3-D version is introduced, the 2-D version quickly becomes confusing for any creature on this planet.

The question now: shall I do the HSL sphere?

Wednesday, July 02, 2008

Converting between HSL and HSV

Amazingly, tons of code fragments on how to convert between RGB and HSV as well as between RGB and HSL do exist (in any imagineable programming languages). However, googling for HSL to HSV conversion did not reveal anything useful. Maybe I was blind, but there is really no point wasting minutes for something that (should be trivial). A quick glance at the wikipedia article on HSL and HSV gave me the following code:

 1 void hsv_to_hsl(double h, double s, double v,
 2 double* hh, double* ss, double *ll)
 3 {
 4     *hh = h;
 5     *ll = (2 - s) * v;
 6     *ss = s * v;
 7     *ss /= (*ll <= 1) ? (*ll) : 2 - (*ll);
 8     *ll /= 2;
 9 }
10
11 void hsl_to_hsv(double hh, double ss, double ll,
12 double* h, double* s, double *v)
13 {
14     *h = hh;
15     ll *= 2;
16     ss *= (ll <= 1) ? ll : 2 - ll;
17     *v = (ll + ss) / 2;
18     *s = (2 * ss) / (ll + ss);
19 }

Error checking is left as an exercise to the reader, corrections are welcomed. If the code seems to be cryptic, then there is a reason to take a napkin and jot some stuff there...

Sunday, June 29, 2008

return of the graphics dojo: OpenGL-accelerated widgets and Bloom effect

After almost a year without any sign of life, Samuel and I decide that we should resurrect the Graphics Dojo, i.e. by populating it with some new fresh examples.

Being a graphics ninja, Samuel's first example is on how to (finally) put widgets on OpenGL viewport. This is now made possible thanks to Qt 4.4's new feature of adding widgets to the graphics scene. Check out his example code, it looks awesome and you can play with it for hours!

Qt widgets and OpenGL

Since I'm new to all this magical graphics world, my first example is however fairly simple: Bloom effect (with pure Qt of course). If you are an avid gamer, you know what I am talking about here. And just for the fun of it, I coded it so that you can drag-and-drop an image right from the web browser, e.g. Blooming your favorite Flickr photo easily.

Feedback is warmly welcomed. Enjoy!

Bloom effect with Qt

Sunday, June 22, 2008

on Jim Rohn quotes

Jim Rohn quotes have been always my favorites. Here are my picks:

  • Success is doing ordinary things extraordinarily well
  • Maturity is the ability to reap without apology and not complain when things don't go well
  • Miss a meal if you have to, but don't miss a book
  • Let others lead small lives, but not you. Let others argue over small things, but not you. Let others cry over small hurts, but not you. Let others leave their future in someone else's hands, but not you

midnight in Oslo

Taken today, half an hour past midnight, where the night lasts for only roughly 5 hours 10 minutes. And Oslo is only at 59° 56' North. I wish I would have gone further north.

Sunday, June 15, 2008

JavaScript speed race

Just for fun, I tested JavaScript performance of several web browsers, using the well-known SunSpider benchmark tool. The test machine is a fairly old Fujitsu-Siemens Amilo notebook with AMD Turion64 1.8 GHz processor and 1 GB RAM, running Microsoft Windows XP SP2.

SunSpider benchmark results

The result is not surprising. Internet Explorer is notoriously slow but there is hope with IE8. Mozilla developers have done a great job optimizing Firefox. WebKit with SquirrelFish (and surely the upcoming Safari 4) really shines in speed.

Tuesday, June 03, 2008

creating fancy screenshots with Screenie

Screenshot of SpeedCrunch composed using Screenie

There are tons of open-source projects, on SourceForge, Google Code, etc. If you check a project, most likely you see the screenshots first (don't be ashamed, to look at a screenshot is human). And there lies the problem. There is a fairly small amount of coders that are both very good at writing codes and composing good-looking screenshots.

So we had a terribly hot weekend in Oslo. Too hot to be outside the whole day. So after populating the wonderful weekend with banana brownies (I still favor the one with mango, though), fresh chocolate waffles (let's see if I can still continue the Sunday morning waffle tradition), huge delicious pizza (as usual I underestimated the size), pasta bolognese ala myself (but still can't beat the best one, so I was told), every now and then my own interpretation of alcohol-free SOTB (guess what it is. hint: a cocktail of course), and finally some of the worse sushi rolls I ever made (they got it right when they say practice makes perfect), I still have some free time. Then...

I sat down and checked again this old piece of code, Screenie, that I never had time to finish (note to self: do that more often and clean up the junk). It was a tool to compose a screenshot with some style. By style here I mean of course just copy Apple. Why? If you check e.g. Apple Keynote site, you see the proof that simple transformation and effects can make a big difference. What Screenie can do for you should be predictable: to create a screenshot like that.

Assuming you have Qt 4.4 and git, here are the steps:

git clone git://github.com/ariya/screenie.git
cd screenie && qmake && make

(Likely you need qmake-qt4 for (K)ubuntu and Debian).

Basically you have a window where you can drag-and-drop an image from Konqueror (either local file or from the Internet) and place it there. You have three spots on the screen to fill. Tweak the parameters to achieve the 3-D goodness and translucent reflection that you want. Finally right-click to save the result.

As some Apple web pages show, there are certain cases where you want two images instead of three. So use your imagination and the check boxes are at your disposal. In the following example, I just drag-and-drop the two Plasma screenshots (one, two) I have on my Flickr straight from Konqueror. Don't you agree that visually it does make a difference?

Plasma screenshot composed using Screenie

Benjamin was already playing with that. Helder was using it for SpeedCrunch. Who else wants to join the club?

Monday, June 02, 2008

Web Inspector under Linux

Are you a web developer, using Linux, and still running Safari under Wine to use its lovely Web Inspector? How about an alternative: use Web Inspector natively under Linux, e.g. inside Arora. Check out my blog post on Trolltech Labs for details.

The obligatory screenshot for your pleasure:

Web Inspector in Arora