{"id":1959,"date":"2008-10-24T11:06:06","date_gmt":"2008-10-24T16:06:06","guid":{"rendered":"http:\/\/www.shamusyoung.com\/twentysidedtale\/?p=1959"},"modified":"2008-10-24T19:47:41","modified_gmt":"2008-10-25T00:47:41","slug":"getbitmapbits","status":"publish","type":"post","link":"https:\/\/www.shamusyoung.com\/twentysidedtale\/?p=1959","title":{"rendered":"GetBitmapBits ()"},"content":{"rendered":"<div class=\"dmnotes\">This is just venting about some project annoyances that I needed to get off my chest.  No gaming news or rants about DRM today.  Read on to be bored by trivialities&#8230;<\/div>\n<p>I have no less than a week&#8217;s worth of posts sitting in the queue, in much the same way that wet leaves might sit in your downspout, preventing efficient operation.  All of them need that once-over in different places to weed out different places where I re-use words and the bad sentence structure in different places.  <\/p>\n<p>Next week I&#8217;m going to put up my long-delayed survival horror posts up for Halloween, so some of these posts will be stale by the time we reach them.  Which do you prefer, unfinished, or irrelevant?  No worries, I can do both!<\/p>\n<p>I should have spent tonight (Thursday) on Friday&#8217;s noontime post, but instead I got caught up in a side project&#8230;  <\/p>\n<p>I&#8217;ve mentioned elsewhere that I build <a href=\"http:\/\/www.escapistmagazine.com\/articles\/view\/comics\/stolen-pixels\">my comics<\/a> using a homebrew program I came up with.  It lets me throw down word bubbles and drag the tails around and generally do stuff that would be tedious and time consuming if done by hand.  <\/p>\n<p>But for months I&#8217;ve been irritated at how long it takes to update a bubble.  When I type text into the dialog box, it takes a full second for the program to rebuild the bubble.  This makes editing really annoying.  At the heart of the problem are the Windows API calls I&#8217;m making.  I draw the text into an off-screen Bitmap using common Windows text-drawing calls.  The same ones used to draw the tooltips and menus in front of you right now if you&#8217;re on a Windows machine.  But for whatever perverse reason, Windows takes preposterous amount of time to give me the data.<\/p>\n<p>It goes like this:<br \/>\n<!--more--><\/p>\n<blockquote><p><em>Me: Hey Windows. You know that bitmap with all the words I just drew?<\/em><\/p>\n<p><strong>Windows: Oh yeah.  Got it right here.  You want me to save that to disk?  Or maybe I should draw it on screen for you? Or maybe-<\/strong><\/p>\n<p><em>Me:  Actually, could you just give it to me?<br \/>\n<\/em><\/p>\n<p><strong>Windows:  You&#8230; what?  What do you want it for?  I can save it or draw it.  What else could you possibly&#8230;<\/strong><\/p>\n<p><em>Me: Please? Just hand over the raw data. I know what I&#8217;m doing. Just let me GetBitmapBits ().<\/em><\/p>\n<p><strong>Windows: Ok.  Geeze.  Hang tight.  Give me some time to get all that together for you.<\/strong><\/p>\n<p><em>Me: But I just need access to data you&#8217;ve already got.  You could just give me a pointer to&#8230;<\/em><\/p>\n<p><strong>Windows: Ngh. Huff huff huff. Oh this hurts.<\/strong><\/p>\n<p><em>Me: What?<\/em><\/p>\n<p><strong>Windows: Oh geeze.  Here&#8230; it&#8230; comes&#8230;<\/strong><\/p>\n<p><em>Me: We&#8217;re talking about 256k of data here.  That&#8217;s peanuts.  This is ridiculous&#8230;<\/em><\/p>\n<p><strong>Windows: Gasp! Whew. That was a toughie.  Here you go.  Please don&#8217;t ask me to do that again.<\/strong><\/p>\n<p><em>Me:  Actually, you took so long on that that the user has typed another letter by now. We&#8217;ve gotta do it all again.<\/em><\/p>\n<p><strong>Windows:  Okay.  Just give me a second to psyche myself up for this.<\/strong><\/p>\n<p><em>Me: Do you understand?!?  YOU ARE OPERATING SLOWER THAN A HUMAN BEING CAN TYPE!  This is NOT 1987!  Pull yourself together!<\/em><\/p>\n<p><strong>Windows: Ngh. Huff huff huff. Oh this hurts.<\/strong><\/p><\/blockquote>\n<p>I realized that I could do the job in under a millisecond (about 200 to 500 times faster, depending on the size of the bubble)  if I dump the Windows crap and do all my font drawing in OpenGL. (Which is what I&#8217;m using to render the comics.)  I can eliminate this entire mess by simply drawing into a texture map.  The only cost is that I have to re-write all the font-drawing code myself.  <\/p>\n<p>This is a terrible time to do something like this, when I&#8217;m already behind on my webcomic and I have posts that need my attention.  But inspiration (which in this case looks a lot like exasperation) is a capricious master and there&#8217;s no use in trying to write jokes when my mind wants to write code.<\/p>\n<p>My program takes text and arranges it in an oval of variable size <em>and<\/em> aspect. (Never taller than it is wide.) The aesthetic arranging of words in a circular region is insanely complex.  This is a job usually done by some sort of &#8220;artist&#8221; who uses a lot of &#8220;intuition&#8221;, which is just the sort of thing you want to avoid trying to turn into code.  <\/p>\n<p>The only two things I needed from windows is for it to tell me how big a word was (how big of a rectangle it occupies) and for it to draw that word.  My program is experimenting with hundreds and hundreds of layouts before it finds just the right one, and then calculates how tight it needs to make the oval to contain the contents. It&#8217;s doing all of this complex stuff and then gags on blitting a medium-sized block of data, which should, in a sane world, be so fast I should have trouble measuring it with my millisecond-resolution timer.   <\/p>\n<p>I shudder to imagine what madness Windows must be working behind the scenes for it to spend that much time on it.  <\/p>\n<p>This is classic programmer behavior:  To spend two hours writing code so that I can save a half-second per letter.  Why, after 14,400 letters I&#8217;ll have saved enough time to justify the work I put into it! (It&#8217;s not so much the time that&#8217;s motivating me anyway.  It&#8217;s the desire to Do It Right.) <\/p>\n<p>And I realize I just blew even more time typing this up, but if you&#8217;re a programmer you&#8217;ll understand why I needed to do this.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is just venting about some project annoyances that I needed to get off my chest. No gaming news or rants about DRM today. Read on to be bored by trivialities&#8230; I have no less than a week&#8217;s worth of posts sitting in the queue, in much the same way that wet leaves might sit [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10],"tags":[],"class_list":["post-1959","post","type-post","status-publish","format-standard","hentry","category-projects"],"_links":{"self":[{"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=\/wp\/v2\/posts\/1959","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1959"}],"version-history":[{"count":0,"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=\/wp\/v2\/posts\/1959\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1959"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1959"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1959"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}