2015-11-23 2 views
-4

Я эмулировал экран с библиотекой SDL. Я хочу нарисовать шрифты на этом экране, просто используя функцию «draw_pixel», которую я уже сделал.Рисование шрифтов на экране в C

Я много искал в Интернете. Я нашел этот сайт http://jared.geek.nz/2014/jan/custom-fonts-for-microcontrollers, и код работает хорошо. Однако он не поддерживает символы переменной ширины

Я только хочу использовать исходный код.

Не могли бы вы рассказать мне, есть ли исходный код или световая библиотека для рисования шрифтов из пикселей?

EDIT: Вот мой код, который я изменил с ответа М Oehm.

int DrawChar(char c, uint8_t x, uint8_t y, int r, int g, int b, SDL_Surface *rectangle, SDL_Surface *ecran, SDL_Rect position) 
{ 
uint8_t i,j; 

// Convert the character to an index 
c = c & 0x7F; 
if (c < ' ') { 
    c = 0; 
} else { 
    c -= ' '; 
} 

const uint8_t* chr = font[c]; 
int w = chr[0]; 

chr++; 

for (j = 0; j < w; j++) { 
    for (i = 0; i < CHAR_HEIGHT; i++) { 

     if (chr[j] & (1 << i)) { 
      draw_pixel(x+j, y+i, r, g, b, rectangle, ecran, position); 
     } 
    } 
} 

return w + CHAR_GAP; 
} 

void DrawString(const char* str, uint8_t x, uint8_t y, int r, int g, int b, SDL_Surface *rectangle, SDL_Surface *ecran, SDL_Rect position) 
{ 
while (*str) { 
    x += DrawChar(*str++, x, y, r, g, b, rectangle, ecran, position); 
} 
} 

const unsigned char font[96][6] = { 
{3, 0x00, 0x00, 0x00},   // 
{3, 0x00, 0x2f, 0x00},   // ! 
{4, 0x03, 0x00, 0x00, 0x03}, // " 

Вот результат: персонажи все еще в том же размере. http://hpics.li/d54f000

EDIT: Решение здесь http://www.riuson.com/lcd-image-converter Вам придется немного изменить код, потому что они какие-то ошибки, но это работает.

ответ

1

Вы можете легко расширить данный код до символов переменной ширины. Измените определение шрифта:

const unsigned char font[96][10] = { 
    {3, 0x00, 0x00, 0x00},   // 
    {3, 0x00, 0x2f, 0x00},   // ! 
    {4, 0x03, 0x00, 0x00, 0x03}, // " 
    ... 
}; 

Первая запись - это ширина символа. Второе измерение должно быть выбрано для размещения самого широкого символа. В этом примере это может быть 9 пикселей.

Затем удлините функцию DrawChar, чтобы использовать заданную ширину и alo, чтобы вернуть ширину, которую должно выполнить позиция поворота, которая является шириной символа плюс определенный промежуток. (Вы можете сделать этот разрыв параметр, так что вы можете напечатать двойной интервал текста.)

DrawString функция затем использует возвращаемой ширина:

int DrawChar(char c, uint8 x, uint8 y, uint8 brightness) 
{ 
    uint8 i, j; 

    // Convert the character to an index 
    c = c & 0x7F; 
    if (c < ' ') { 
     c = 0; 
    } else { 
     c -= ' '; 
    } 

    const uint8* chr = font[c]; 
    int w = chr[0]; 

    chr++; 

    for (j = 0; j < w; j++) { 
     for (i = 0; i < CHAR_HEIGHT; i++) { 

      if (chr[j] & (1 << i)) { 
       DrawPixel(x + j, y + i, brightness); 
      } 
     } 
    } 

    return w + CHAR_GAP; 
} 

void DrawString(const char* str, uint8 x, uint8 y, uint8 brightness) 
{ 
    while (*str) { 
     x += DrawChar(*str++, x, y, brightness); 
    } 
} 

Edit: Вот более полный пример, который определяет только некоторые буквы:

#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 

typedef unsigned char uint8; 

char screen[25][80]; 

#define CHAR_HEIGHT 8 
#define CHAR_GAP 2 

const unsigned char font[96][10] = { 
    [' ' - 32] = {1, 0x00}, 
    ['A' - 32] = {5, 0x3e, 0x09, 0x09, 0x09, 0x3e}, 
    ['B' - 32] = {5, 0x3f, 0x25, 0x25, 0x25, 0x19}, 
    ['D' - 32] = {5, 0x3f, 0x21, 0x21, 0x21, 0x1e}, 
    ['E' - 32] = {5, 0x3f, 0x25, 0x25, 0x25, 0x21}, 
    ['H' - 32] = {5, 0x3f, 0x04, 0x04, 0x04, 0x3f}, 
    ['I' - 32] = {1, 0x3f}, 
    ['L' - 32] = {4, 0x3f, 0x20, 0x20, 0x20}, 
    ['M' - 32] = {7, 0x3f, 0x02, 0x04, 0x18, 0x04, 0x02, 0x3f}, 
    ['O' - 32] = {5, 0x1e, 0x21, 0x21, 0x21, 0x1e}, 
    ['P' - 32] = {5, 0x3f, 0x09, 0x09, 0x09, 0x06}, 
    ['R' - 32] = {5, 0x3f, 0x09, 0x19, 0x19, 0x26}, 
    ['S' - 32] = {5, 0x22, 0x25, 0x25, 0x25, 0x19}, 
    ['W' - 32] = {7, 0x07, 0x38, 0x0c, 0x03, 0x0c, 0x38, 0x07}, 
}; 

void DrawPixel(int x, int y, uint8 c) 
{ 
    screen[y][x] = c; 
} 

int DrawChar(char c, uint8 x, uint8 y, uint8 brightness) 
{ 
    uint8 i, j; 

    // Convert the character to an index 
    c = c & 0x7F; 
    if (c < ' ') { 
     c = 0; 
    } else { 
     c -= ' '; 
    } 

    const uint8* chr = font[c]; 
    int w = chr[0]; 

    chr++; 

    for (j = 0; j < w; j++) { 
     for (i = 0; i < CHAR_HEIGHT; i++) { 

      if (chr[j] & (1 << i)) { 
       DrawPixel(x + j, y + i, brightness); 
      } 
     } 
    } 

    return w + CHAR_GAP; 
} 

void DrawString(const char* str, uint8 x, uint8 y, uint8 brightness) 
{ 
    while (*str) { 
     x += DrawChar(*str++, x, y, brightness); 
    } 
} 

int main() 
{ 
    int i; 

    memset(screen, '.', sizeof(screen)); 

    DrawString("HELLO WORLD", 2, 2, 'O'); 
    DrawString("MISSISSIPPI", 8, 10, '#'); 

    for (i = 0; i < 25; i++) printf("%.80s\n", screen[i]); 

    return 0; 
} 
+0

@M Oehm благодарит за ваш ответ. Я пробовал ваш код, но он не работает. Действительно, если я изменяю первую запись (ширину символа), тогда она рисует больше пикселей рядом с символом. Но она не меняет ее. – Johnrednex

+0

Хммм, я протестировал этот код, хотя и не с полным алфавитом. Вы скопировали мой код или только что внесли изменения? –

+0

Я только что внес изменения. – Johnrednex