首页 > 解决方案 > How to draw TrueType fonts into an array of pixels in WinAPI?

问题描述

There are some WinAPI functions that draw TrueType fonts into a windows GDI context.

I want to have this TrueType text written, but into my own 2-dimensional array of pixels (the one I just blit onto a 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 code is very messy in WinAPI and I couldn't find out (at least to this moment) how to do that.

How can I do that?

标签: winapifontsgditruetype

解决方案


tnx 巴马克谢米拉尼

我得到你的代码并产生了类似的东西

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);
}

它为我的 blitted 帧添加了稳定的文本,tnx

悬停我会得到一些问题,因为我不明白

1)也许有人可以告诉我更多它是如何工作的以及内存传输在哪里?我对这个用绘制文本更新的像素表有简单的字节访问吗?(例如对它进行后处理)

2)它可以工作,但它变得很慢,例如当我的原始帧是 2 毫秒(绘制一些位图精灵然后 blit)时,当使用这个驯服时增长到 8 毫秒

3)我可以将其中一些调用移到帧循环之外吗?

PS 在考虑这个问题时,我假设它是这样工作的 1)它会在某个时候(在哪里?)将我的像素表复制到 memdc 中(在哪里?) 2)它会将那些字体绘制到这个 memdc 3)GetDIBits 用改变的像素更新我的原始像素表(我不是确定这个悬停,但几乎可以肯定)4)我像以前一样blit它

如果是这样,而不是一个 blit 我得到三个(它应该慢 3 倍,测量显示它更像是 4 倍,但可能它是一个测量误差(例如,2 和 8 可能是 2.7 和 8.1)

如果这是三个就可以了,但是我认为我并不总是需要从 memdc 重新更新那些表格像素,有没有办法直接从 memdc 中删除它?(那么它只会慢两倍而不是 3 倍,但遗憾的是那些 fount 例程不能直接渲染到我自己的 ram 表中 - 那么它根本不会慢)(真的可能吗?)


推荐阅读