You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

88 lines
3.5 KiB

  1. #include "fbg_utils.h"
  2. #include <stdint.h>
  3. void swap_bgr(struct color_rgb* color)
  4. {
  5. uint8_t t = color->r;
  6. color->r = color->b;
  7. color->b = t;
  8. }
  9. uint8_t alpha_blend(uint8_t b, uint8_t f, uint8_t a)
  10. {
  11. return (f * a + b * (255 - a)) >> 8;
  12. }
  13. uint8_t alpha_blend_abc(uint8_t b, uint8_t f1, uint8_t f2, uint8_t a1, uint8_t a2)
  14. {
  15. return alpha_blend(alpha_blend(b, f1, a1), f2, a2);
  16. }
  17. void draw_font(struct _fbg* f, struct font_render_buffer* src, int x, int y,
  18. struct color_rgb color)
  19. {
  20. if (f->bgr)
  21. swap_bgr(&color);
  22. for (int i = 0; i < src->height && i + y < f->height; i++) {
  23. for (int j = 0; j < src->width && j + x < f->width; j++) {
  24. uint_fast8_t alpha = src->data[i * src->width + j];
  25. if (alpha == 0)
  26. continue;
  27. int oIndex = ((i + y) * f->width + j + x) * f->components;
  28. f->back_buffer[oIndex] = alpha_blend(f->back_buffer[oIndex], color.r, alpha);
  29. f->back_buffer[oIndex + 1] = alpha_blend(f->back_buffer[oIndex + 1], color.g, alpha);
  30. f->back_buffer[oIndex + 2] = alpha_blend(f->back_buffer[oIndex + 1], color.b, alpha);
  31. }
  32. }
  33. }
  34. void draw_font_border(struct _fbg* f, struct font_render_buffer* src, int x, int y,
  35. struct color_rgb color, struct color_rgb border_color)
  36. {
  37. if (f->bgr) {
  38. swap_bgr(&color);
  39. swap_bgr(&border_color);
  40. }
  41. for (int i = 0; i < src->height && i + y < f->height; i++) {
  42. for (int j = 0; j < src->width && j + x < f->width; j++) {
  43. uint_fast8_t alpha = src->data[i * src->width + j];
  44. if (alpha == 0)
  45. continue;
  46. uint_fast8_t border_alpha = alpha & 0xf0;
  47. uint_fast8_t font_alpha = alpha << 4;
  48. int oIndex = ((i + y) * f->width + j + x) * f->components;
  49. f->back_buffer[oIndex] = alpha_blend_abc(f->back_buffer[oIndex], border_color.r, color.r, border_alpha, font_alpha);
  50. f->back_buffer[oIndex + 1] = alpha_blend_abc(f->back_buffer[oIndex + 1], border_color.g, color.g, border_alpha, font_alpha);
  51. f->back_buffer[oIndex + 2] = alpha_blend_abc(f->back_buffer[oIndex + 1], border_color.b, color.b, border_alpha, font_alpha);
  52. }
  53. }
  54. }
  55. void image_data_to_buffer(struct _fbg* fbg, struct image_data* img, struct _fbg_img* outImg)
  56. {
  57. if (outImg->height < img->height || outImg->width < img->width)
  58. return;
  59. for (int y = 0; y < img->height; y++) {
  60. if (fbg->components == 3 && !fbg->bgr) {
  61. memcpy(outImg->data + y * outImg->width * fbg->components,
  62. img->data + (y * img->width * 3),
  63. img->width * 3);
  64. } else {
  65. for (int x = 0; x < img->width; x++) {
  66. if (fbg->bgr) {
  67. outImg->data[(y * outImg->width + x) * fbg->components + 0] = img->data[(y * outImg->width + x) * 3 + 2];
  68. outImg->data[(y * outImg->width + x) * fbg->components + 1] = img->data[(y * outImg->width + x) * 3 + 1];
  69. outImg->data[(y * outImg->width + x) * fbg->components + 2] = img->data[(y * outImg->width + x) * 3 + 0];
  70. } else {
  71. outImg->data[(y * outImg->width + x) * fbg->components + 0] = img->data[(y * outImg->width + x) * 3 + 0];
  72. outImg->data[(y * outImg->width + x) * fbg->components + 1] = img->data[(y * outImg->width + x) * 3 + 1];
  73. outImg->data[(y * outImg->width + x) * fbg->components + 2] = img->data[(y * outImg->width + x) * 3 + 2];
  74. }
  75. }
  76. }
  77. }
  78. }