Как нарисовать шрифты TrueType в массив пикселей в WinAPI?

Есть несколько функций WinAPI, которые рисуют шрифты TrueType в контексте GDI Windows.

Я хочу, чтобы этот текст TrueType был написан, но в моем собственном двумерном массиве пикселей (тот, который я просто перенес в окно с помощью этого кода :)

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

Этот код в WinAPI очень беспорядочный, и я не мог понять (по крайней мере, на данный момент), как это сделать.

Как я могу это сделать?

Найдите «контекст устройства памяти» и «растровое изображение, независимое от устройства».

zett42 08.08.2018 22:35

В книге Петцольда «Программирование Windows» объясняются растровые изображения, контексты устройств и их взаимосвязь. Понимание концепций, с которыми вы работаете, - эффективная и действенная стратегия в будущем.

IInspectable 08.08.2018 22:40

странная вещь: даже если я не буду отображать эти глифы в моем растровом изображении (что я не знаю, как это сделать, и что очень приветствуется, потому что тогда я мог бы постобработать его с помощью моего процессора и т.д.), я просто переношу свою таблицу пикселей в окно, ЗАТЕМ визуализирую этот текст тоже в окно - тогда он тоже не работает, он мерцает ... Я не понимаю, почему ... все это делается за одну процедуру рисования, и мне не кажется, что это следует рассматривать как две отдельные перерисовки, даже если между этими двумя рисунками есть небольшой промежуток времени ... странный вывод может заключаться в том, что окна не буферизируют его до завершения процедуры рисования, а показывают его в реальном времени

J. Stone 08.08.2018 23:44

если так, то это действительно странно ... тогда мне нужны те процедуры, которые отображают его в моем массиве ... байт, почему все это так запутанно и такой беспорядок

J. Stone 08.08.2018 23:46

Вам это кажется беспорядком, потому что вы отказываетесь выполнять основную работу и изучаете анатомию системы, с которой работаете. Прочтите документацию Сообщение WM_PAINT, чтобы понять, почему ваше решение мерцает. А еще лучше получить Программирование Windows® Петцольда. Это наиболее эффективный способ изучить программирование для Windows.

IInspectable 09.08.2018 00:16

См. Это пример

Barmak Shemirani 09.08.2018 05:51
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
6
219
1

Ответы 1

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

он добавляет стабильный текст в мои слитные фреймы, tnx

Hovever я бы получил еще несколько вопросов, так как я этого не понимаю

1) Может быть, кто-нибудь расскажет мне немного подробнее, как это работает и где происходит передача памяти? у меня есть простой байтовый доступ к этой таблице пикселей, которая обновляется нарисованным текстом? (например, для постобработки)

2) он работает, но становится заметно медленнее, например, когда мой исходный кадр составлял 2 мс (нарисуйте немного растрового спрайта, а затем блит), при использовании этого приручения он увеличивается до 8 мс

3) могу ли я переместить некоторые из этих вызовов за пределы цикла кадра?

PS размышляя об этом, я предполагаю, что это работает так 1) он копирует мою таблицу пикселей в memdc в какой-то момент (где?) 2) он рисует в этом memdc эти шрифты 3) GetDIBits обновляет мою исходную таблицу пикселей измененными пикселями (я не уверен в этом наведении, но почти уверен) 4) я делаю это так же, как раньше

если так, то вместо одного блит я получаю три (он должен быть в 3 раза медленнее, измерения показывают, что это больше похоже на 4 раза, но, возможно, это ошибка измерения (например, 2 и 8 могут быть 2,7 и 8,1)

если это три, все будет в порядке, но я думаю, мне не всегда нужно повторно обновлять эти пиксели таблицы из memdc, есть ли способ били это прямо из memdc? (тогда это было бы только в два раза медленнее, а не в 3, все же грустно, что эти подпрограммы fount не могут просто отображать прямо в моей собственной таблице ram - тогда это было бы совсем не медленнее) (разве это не возможно?)

Какова ваша цель? Вы можете использовать память постоянного тока для рисования на растровом изображении. Вы также можете использовать память постоянного тока в качестве буфера рисования. BitBlit или StretchBlt, чтобы пропустить функции BITMAPINFO. Использование hdc кажется неправильным. hdc - это временный дескриптор, его можно передавать, но не следует хранить - кстати, вы можете обновить вопрос или удалить ответ и вопрос, вместо этого задать новый вопрос.

Barmak Shemirani 09.08.2018 21:28

Подпрограммы рендеринга шрифтов GDI может визуализируют прямо в контексте устройства, поддерживая точечный рисунок в памяти. Чтобы это увидеть, нужно понимать контексты устройств.

IInspectable 11.08.2018 13:17

Другие вопросы по теме