Discussion:
drawing ttf fonts into a ram array of pixels
(too old to reply)
fir
2018-08-08 18:44:33 UTC
Permalink
there are some winapi functions that draw
true type fonts into window gdi context

i want to have thistrue type text written but into my own 2-dimensional array of pixels
(the one i just blit onto window with just this code:)

int blit_mode = STRETCH_DELETESCANS;

void BlitFrame()
{

BITMAPINFO bmi = { {sizeof(BITMAPINFOHEADER), frame_size_x, -frame_size_y,1,32,BI_RGB,0,0,0,0,0}, {0,0,0,0} };

SetStretchBltMode(hdc, blit_mode);

int result = StretchDIBits(hdc,
0, 0, client_x, client_y,
0, 0, frame_size_x, frame_size_y,
frame_bitmap,
&bmi,
DIB_RGB_COLORS,
SRCCOPY);
}


this shit is very messy in winapi and i couldnt finf (at least to this moment ) how to do that- how to do that?

HELP
R.Wieser
2018-08-08 21:07:48 UTC
Permalink
Fir,
Post by fir
i want to have thistrue type text written but into my own 2-dimensional array of pixels
To be able to do that you need to create a (compatible) DC and select your
bitmap into it. Only than you can draw onto your bitmap.

Don't forget to, when you're done drawing, to restore the DCs old contents
(thereby removing your bitmap) and than deleting the DC itself (otherwise
you get GDI leaks)

Regards,
Rudy Wieser
fir
2018-08-08 21:59:04 UTC
Permalink
Post by R.Wieser
Fir,
Post by fir
i want to have thistrue type text written but into my own 2-dimensional array of pixels
To be able to do that you need to create a (compatible) DC and select your
bitmap into it. Only than you can draw onto your bitmap.
Don't forget to, when you're done drawing, to restore the DCs old contents
(thereby removing your bitmap) and than deleting the DC itself (otherwise
you get GDI leaks)
could yu maybe wrote those few lines?
i get no used to those mess

i may imagine roughly like it should look like: something like this?

new_hdc = CreteCompatibleDC(hdc);
BlitMyBitmapInto(new_hdc)
DrawMyWinapiFontsInto(new_hdc);
BlitNewHDCInto(hdc)

it is sad i will get two blits instead of one.. hovever i could probably live with that (though not in all cases, if for example resolution is high this is a lot of wasted memory bandwidth and very noticable framerate drop)
fir
2018-08-09 07:14:33 UTC
Permalink
ok i found some answer on stack O, hovever some questions are still not resolved, see copy of my post


tnx Barmak Shemirani

i get your code and produced something like that

void BlitFrame2()
{

BITMAPINFO bmi = { {sizeof(BITMAPINFOHEADER), frame_size_x, -frame_size_y,1,32,BI_RGB,0,0,0,0,0}, {0,0,0,0} };


HDC memdc = CreateCompatibleDC(hdc);
HBITMAP hbitmap = CreateBitmap(frame_size_x, frame_size_y, 1, 32, frame_bitmap);
HGDIOBJ oldbmp = SelectObject(memdc, hbitmap);

SetBkMode(memdc, TRANSPARENT);
SetTextColor(memdc, 0xffffff);
TextOut(memdc, 0, 0, "123", 3);

SelectObject(memdc, oldbmp);
GetDIBits(memdc, hbitmap, 0, frame_size_y, frame_bitmap, &bmi, 0);
DeleteObject(hbitmap);
DeleteDC(memdc);

// ReleaseDC(0, hdc);

SetStretchBltMode(hdc, blit_mode);

int result = StretchDIBits(hdc,
0, 0, client_x, client_y,
0, 0, frame_size_x, frame_size_y,
frame_bitmap,
&bmi,
DIB_RGB_COLORS,
SRCCOPY);
}
its adds stable text to my blitted frames, tnx

hovever i would get yet some question as i dont understand it

1) could maybe someone tell me a bit more how it works and where memory transfers are? do i have simple byte acces to this pixel table that is updated with drawed text? (for example to postprocess it)

2) it works but it gets slower quite noticably, for example when my oryginal frame was 2 ms (draw some bitmap sprite then blit) when using this tame grows up to 8 ms

3) can i move some of those calls outside of frame loop?

PS when thinking on this i assume it works like that 1) it copies my pixel table in memdc at some point (where?) 2) it draws to this memdc those fonts 3) GetDIBits updates my oryginal pixel table with changed pixels (im not sure as to this hovever, but almost sure) 4) i blit it just like before

if so instead of one blit i get three (co it should be 3 times slower, measurements show its more like 4 times, but maybe its an measurment error (2 and 8 may be 2.7 and 8.1 for example)

if this is three it would be ok, hovever i think i not always would need to get those table pixels reupdated from memdc, is there a way of blitting it stright from memdc? (then it would be only two times slower instead of 3, still it is sad those fount routines cant just render stright into my own ram table - then it would be no slower at all) (isnt it really possible?)
R.Wieser
2018-08-09 07:43:17 UTC
Permalink
Fir,
Post by fir
1) could maybe someone tell me a bit more how it works and
where memory transfers are?
I'm sorry, but I have no idea how exactly the whole thing works at that
level.
Post by fir
do i have simple byte acces to this pixel table that is updated
with drawed text? (for example to postprocess it)
Yes. You can create a bitmap with raster data access. That allows you
to read and/or write the raw data.
Post by fir
2) & 3) can i move some of those calls outside of frame loop?
Ofcourse. You can create the DC and set its attributes (color, mode) once.
If your bitmap stays the same you only need to create it once too (there is
a FillRect function available to erase its contents).
Post by fir
PS when thinking on this i assume it works like that 1) it
copies my pixel table in memdc at some point
I don't think so. Its more likely the drawing will be done directly onto
that canvas (your bitmap), with the DC selecting the apropriate routines for
it (in relation to bitdepth and how/where the colors are supposed to be
stored).

Also, you would than need to use an "update original canvas from DC" command
when you would, as suggested in the above, move the initialisation of the DC
and bitmap outside of the loop, something I do not remember having found or
used.

Regards,
Rudy Wieser
fir
2018-08-09 16:12:08 UTC
Permalink
Post by R.Wieser
Fir,
Post by fir
1) could maybe someone tell me a bit more how it works and
where memory transfers are?
I'm sorry, but I have no idea how exactly the whole thing works at that
level.
Post by fir
do i have simple byte acces to this pixel table that is updated
with drawed text? (for example to postprocess it)
Yes. You can create a bitmap with raster data access. That allows you
to read and/or write the raw data.
HOW?
Post by R.Wieser
Post by fir
2) & 3) can i move some of those calls outside of frame loop?
Ofcourse. You can create the DC and set its attributes (color, mode) once.
If your bitmap stays the same you only need to create it once too (there is
a FillRect function available to erase its contents).
WHAT IF SIZE/FORMAT IS THE SAME BUT CONTENTS (OF MY PIXEL TABLE) ARE CHANGED?
Post by R.Wieser
Post by fir
PS when thinking on this i assume it works like that 1) it
copies my pixel table in memdc at some point
I don't think so. Its more likely the drawing will be done directly onto
that canvas (your bitmap), with the DC selecting the apropriate routines for
it (in relation to bitdepth and how/where the colors are supposed to be
stored).
I DONT TTHINK SO, I WAS MAKING SOME TEST AND IT DONT SEMED SO, HOVEVER AS I GENREALLY DONT UNDERSTAND HOW IT WORK IM NOT SURE (AND AS THAT WEIRD OPAQUE API MAKES STRONG HEADACHE IN MY HEAD I DONT EVEN CAN READ ON THIS, UNTIL MY HEADACHE BARRIER WILL GONE - WIERD EFFECT BUT REALLY)
Post by R.Wieser
Also, you would than need to use an "update original canvas from DC" command
when you would, as suggested in the above, move the initialisation of the DC
and bitmap outside of the loop, something I do not remember having found or
used.
I DONT UNDERSTAND, IN SHORT THE PROBLEM IS THE CODE I POSTED MAKES 3 BLITS WHEN
ORYGINALLY I JUST GET ONE... THE QUESTION IS HOW TO REDUCE IT TO 2 AND
MOST PREFERABLY ONE

THE SOLUTION WOULD BE FORCE TextOut TO BE WRITTING TO MY ARRAY OF PIXELS, (WHICH IS unsigned* frame_data)

HAS THIS memdc THE SAME RAM THATMY ARRAY (ONLY HOLDING POINER?)

I THINK IT SHOULD BE SOME RAM (NOT VIDEO RAM) (OR IS memdc VIDEO RAM?) IF SO IT COULD BE POSSIBLE, BUT HOW?
R.Wieser
2018-08-09 18:32:27 UTC
Permalink
fir,
Post by fir
Post by R.Wieser
Yes. You can create a bitmap with raster data access. That
allows you to read and/or write the raw data.
HOW?
Hmmm... I currently cannot seem to find that specific function (with
read/write access), but what about using GetBitmapBits (GetDIBits) to be
able to read the raw data ?
Post by fir
WHAT IF SIZE/FORMAT IS THE SAME BUT CONTENTS
(OF MY PIXEL TABLE) ARE CHANGED?
Seeing that you are yelling I get it that you are frustrated (for some
reason I'm not quite privvy to). But it doesn't magically make me understand
the problem(s) you have/see. You *really* have to post them.

Also, do you have the include file for te GDI32.DLL handy ? Looking thru
it might give you a few leads to what to do a google for, and that way get
more info.
Post by fir
I DONT TTHINK SO
Skipped. Nothing in there I can do anything with.
Post by fir
IN SHORT THE PROBLEM IS THE CODE I POSTED MAKES
3 BLITS WHEN ORYGINALLY I JUST GET ONE... THE
QUESTION IS HOW TO REDUCE IT TO 2 AND MOST
PREFERABLY ONE
I suggest you show that "3 blits" code, so I/we can comment upon it.



Currently, without that code, all I could do is to *%$!^# *guess* to what
you actually need, write the code for you and serve it on a silver platter

AND THAT IS *NOT* GOING TO HAPPEN !!!

Comprende ?

I'm willing to *help* you. I provide suggestions to what you could/should
be looking for, and you do the work. Take or leave it. Your choice.
Post by fir
THE SOLUTION WOULD BE FORCE TextOut TO BE
WRITTING TO MY ARRAY OF PIXELS, (WHICH IS
unsigned* frame_data)
That is not going to happen. You need to go thru the DC (for reasons I
already explained).
Post by fir
HAS THIS memdc THE SAME RAM THATMY ARRAY
(ONLY HOLDING POINER?)
Nope. That "memdc" also holds settings for drawing mode, color, and
objects for a number of other things (a brush to name one). In short, its
a container for quite a few different things.
Post by fir
I THINK IT SHOULD BE SOME RAM .... IF SO IT
COULD BE POSSIBLE, BUT HOW?
*Ofcourse* its RAM. What else do you think it could be ?

But no, the DC does not give you direct access to it. For good reasons.

Regards,
Rudy Wieser
fir
2018-08-10 11:37:37 UTC
Permalink
i made some tests to be able to deduce something (sometimes easier and faster to test end deduce than reading that google trash)

those are those lines that work but i suspect it for three blits


BITMAPINFO bmi = { {sizeof(BITMAPINFOHEADER), frame_size_x, -frame_size_y,1,32,BI_RGB,0,0,0,0,0}, {0,0,0,0} };

hbitmap = CreateBitmap(frame_size_x, frame_size_y, 1, 32, frame_bitmap);

oldbmp = SelectObject(mem_dc, hbitmap);

/////////////////////////////
// RenderTTFontHEre
//////////////////////////////



GetDIBits(mem_dc, hbitmap, 0, frame_size_y, frame_bitmap, &bmi, 0);

DeleteObject(hbitmap);


SetStretchBltMode(hdc, blit_mode);

int result = StretchDIBits(hdc,
0, 0, client_x, client_y,
0, 0, frame_size_x, frame_size_y,
frame_bitmap,
&bmi,
DIB_RGB_COLORS,
SRCCOPY);

what it showed

I. pure blit (with clear data and some slight drawing) takes 0.5 ms (for small window 500x400)

II. CreateBitmap adds 0.7 ms to it (which is a lot)

III. GetDIBits adds 0.3 ms (its like raw blit time) which is reasonable, though it also confirms it is a blit back into my array (ommiting it seems ttf rendering dont updates my oryginal array)

IV. those calls select object delete object dont seem to add overhead

V. TTF rendaring may add a lot, rendering big truetype firr in helvetica
added 3 ms (which is a lot)

those blit times may still seem not
so deadly (those two additional blits
add +1.0 ms) but it is not exactly true as it grows rapidly with windows size and screen resolution where the cost of it may grow i think to +10 ms or more (maybe even +20 ms)for HD - so it is
bad

now the problem is how to repair/improve
this (and how well understood what those functions really do)
JJ
2018-08-10 18:43:07 UTC
Permalink
Post by fir
what it showed
I. pure blit (with clear data and some slight drawing) takes 0.5 ms
(for small window 500x400)
Doesn't matter whether the image is clear or contains some pattern. The
function only sees pixels. And it'll take longer if the source and
destination bitmaps have different pixel format.
Post by fir
II. CreateBitmap adds 0.7 ms to it (which is a lot)
It creates the bitmap image information and clears the image data. How long
it'll take to finish, would depend on the image data size.
Post by fir
III. GetDIBits adds 0.3 ms (its like raw blit time) which is reasonable,
though it also confirms it is a blit back into my array (ommiting it
seems ttf rendering dont updates my oryginal array)
More like unconditional blit. Because it doesn't need to check whether the
destination pixel format is the same as the source or not.
Post by fir
IV. those calls select object delete object dont seem to add overhead
It does. We just don't notice it. Its main task is simply to set the bitmap,
brush, font, pen, or region, of a device context.
Post by fir
V. TTF rendaring may add a lot, rendering big truetype firr in helvetica
added 3 ms (which is a lot)
Well, vector to raster conversion is not a simple task.
Post by fir
now the problem is how to repair/improve this
GDI is a set of standard issue functions for GUI. While it's relatively
fast, it's not built for speed. GDI+ is just a set of supplemental functions
for more complex image manipulation, and it's still bound by some of GDI
limitations.

Use third party library for working with image, font, and text. i.e. image
manipulation, and font rendering libraries.

For screen display, use either SDL or DirectX. OpenGL or Direct3D can also
be used, but it may get complicated because it'd have to be processed in a
3D manner. Shouldn't be needed unless special effects are needed.
fir
2018-08-11 12:06:31 UTC
Permalink
Post by JJ
Post by fir
what it showed
I. pure blit (with clear data and some slight drawing) takes 0.5 ms
(for small window 500x400)
Doesn't matter whether the image is clear or contains some pattern. The
function only sees pixels. And it'll take longer if the source and
destination bitmaps have different pixel format.
Post by fir
II. CreateBitmap adds 0.7 ms to it (which is a lot)
It creates the bitmap image information and clears the image data. How long
it'll take to finish, would depend on the image data size.
Post by fir
III. GetDIBits adds 0.3 ms (its like raw blit time) which is reasonable,
though it also confirms it is a blit back into my array (ommiting it
seems ttf rendering dont updates my oryginal array)
More like unconditional blit. Because it doesn't need to check whether the
destination pixel format is the same as the source or not.
Post by fir
IV. those calls select object delete object dont seem to add overhead
It does. We just don't notice it. Its main task is simply to set the bitmap,
brush, font, pen, or region, of a device context.
Post by fir
V. TTF rendaring may add a lot, rendering big truetype firr in helvetica
added 3 ms (which is a lot)
Well, vector to raster conversion is not a simple task.
Post by fir
now the problem is how to repair/improve this
GDI is a set of standard issue functions for GUI. While it's relatively
fast, it's not built for speed. GDI+ is just a set of supplemental functions
for more complex image manipulation, and it's still bound by some of GDI
limitations.
Use third party library for working with image, font, and text. i.e. image
manipulation, and font rendering libraries.
For screen display, use either SDL or DirectX. OpenGL or Direct3D can also
be used, but it may get complicated because it'd have to be processed in a
3D manner. Shouldn't be needed unless special effects are needed.
lol, i already forgot such level of lamas still wanders thru usenet...
Loading...