freetype_app.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. // This file is Copyright (c) 2025 Victor Suarez Rovere <suarezvictor@gmail.com>
  2. // SPDX-License-Identifier: AGPL-3.0-only
  3. #include <stdio.h>
  4. #include <assert.h>
  5. #include <stdint.h>
  6. #include "misc.h"
  7. #include "graphics.h"
  8. #include "accel_cores.h"
  9. #include <ft2build.h>
  10. //#include FT_FREETYPE_H
  11. //#include FT_OUTLINE_H
  12. static int y0 = 3*FRAME_HEIGHT/4, x0 = FRAME_HEIGHT/2;
  13. static uint8_t color = 192;
  14. void span_callback(int y, int count, const FT_Span* spans, void* user)
  15. {
  16. for (int i = 0; i < count; ++i)
  17. {
  18. int x = spans[i].x, len = spans[i].len;
  19. if(!len || spans[i].coverage < 128)
  20. continue;
  21. accel_line(accel_line32_regs, x0+x, y0-y, x0+x+len, y0-y, color | 0xFF000000);
  22. }
  23. }
  24. #include "DejaVuSansMono.ttf.c" //inline font data
  25. static FT_Library library;
  26. static FT_Face face;
  27. static FT_Error error;
  28. static FT_UInt glyph_index;
  29. static FT_Raster_Params raster_params;
  30. void setup()
  31. {
  32. // Initialize the FreeType library
  33. error = FT_Init_FreeType(&library);
  34. if (error) {
  35. printf("Could not initialize FreeType library\n");
  36. return;
  37. }
  38. // Load a font face
  39. #if 0
  40. error = FT_New_Face(library, "DejaVuSansMono.ttf", 0, &face);
  41. #else
  42. error = FT_New_Memory_Face(library, (const FT_Byte*) DejaVuSansMono_ttf, DejaVuSansMono_ttf_len, 0, &face);
  43. #endif
  44. if (error == FT_Err_Unknown_File_Format) {
  45. printf("Unsupported font format\n");
  46. FT_Done_FreeType(library);
  47. return;
  48. } else if (error) {
  49. printf("Could not open font file\n");
  50. FT_Done_FreeType(library);
  51. return;
  52. }
  53. // Set the character size
  54. error = FT_Set_Char_Size(face, 0, 32 * 64 * 64, 300, 300);
  55. if (error) {
  56. printf("Could not set character size\n");
  57. FT_Done_Face(face);
  58. FT_Done_FreeType(library);
  59. return;
  60. }
  61. glyph_index = FT_Get_Char_Index(face, 'g'); // Load glyph
  62. error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
  63. if (error) {
  64. printf("Could not load glyph\n");
  65. FT_Done_Face(face);
  66. FT_Done_FreeType(library);
  67. return;
  68. }
  69. memset(&raster_params, 0, sizeof(raster_params));
  70. raster_params.flags = FT_RASTER_FLAG_DIRECT | FT_RASTER_FLAG_AA | FT_RASTER_FLAG_CLIP;
  71. raster_params.gray_spans = span_callback;
  72. raster_params.clip_box.xMin = -x0+10;
  73. raster_params.clip_box.xMax = raster_params.clip_box.xMin + FRAME_WIDTH - 20;
  74. raster_params.clip_box.yMin = -((FRAME_HEIGHT-y0)-10);
  75. raster_params.clip_box.yMax = raster_params.clip_box.yMin + FRAME_HEIGHT - 20;
  76. }
  77. void draw()
  78. {
  79. FT_Outline* src_outline = &face->glyph->outline;
  80. FT_Outline dst_outline;
  81. error = FT_Outline_New(library, src_outline->n_points, src_outline->n_contours, &dst_outline);
  82. error = FT_Outline_Copy(src_outline, &dst_outline);
  83. // Apply a transformation matrix to the outline
  84. static FT_Matrix matrix =
  85. {
  86. .xx = 0x1000, // 0.1 in 16.16 fixed-point
  87. .xy = 0x0000, // 0.0
  88. .yx = 0x0000, // 0.0
  89. .yy = 0x1000, // 0.1
  90. };
  91. //update transform matrix and apply to outline
  92. matrix.xx += 8;
  93. matrix.yy += 8;
  94. FT_Outline_Transform(&dst_outline, &matrix);
  95. // Render the glyph into spans
  96. error = FT_Outline_Render(library, &dst_outline, &raster_params);
  97. if (error) {
  98. printf("Could not render glyph\n");
  99. return;
  100. }
  101. FT_Outline_Done(library, &dst_outline); //only frees memory if owner set (not set with FT_Outline_Copy)
  102. }
  103. extern "C" void graphics_app()
  104. {
  105. memset((void*)VIDEO_FRAMEBUFFER_BASE, 0x40, FRAME_PITCH*FRAME_HEIGHT); //clear buffer
  106. setup();
  107. int frame = 0;
  108. uint64_t t0 = highres_ticks();
  109. for(;;)
  110. {
  111. --color;
  112. draw();
  113. int64_t dt = highres_ticks() - t0;
  114. printf("frame %d, t %d, FPS %d ticks %ld\n",
  115. frame, int(t0/highres_ticks_freq()), int(highres_ticks_freq()/dt), long(dt));
  116. t0 = highres_ticks();
  117. ++frame;
  118. if(color == 255)
  119. break;
  120. }
  121. // Cleanup
  122. FT_Done_Face(face);
  123. FT_Done_FreeType(library);
  124. }
  125. //dependencies
  126. extern "C"
  127. {
  128. //#define FT_DEBUG_LEVEL_TRACE
  129. //#define FT_DEBUG_LEVEL_ERROR
  130. #include "FreeTypeAmalgam.c"
  131. }