main.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735
  1. #include "u8g2.h"
  2. #include <stdint.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <assert.h>
  6. #define WORD_CLOUD_MAX_X 600
  7. extern uint8_t tga_is_transparent;
  8. extern uint8_t tga_desc_fg_r;
  9. extern uint8_t tga_desc_fg_g;
  10. extern uint8_t tga_desc_fg_b;
  11. extern uint8_t tga_desc_bg_r;
  12. extern uint8_t tga_desc_bg_g;
  13. extern uint8_t tga_desc_bg_b;
  14. extern uint8_t tga_lcd_fg_r;
  15. extern uint8_t tga_lcd_fg_g;
  16. extern uint8_t tga_lcd_fg_b;
  17. extern uint8_t tga_lcd_bg_r;
  18. extern uint8_t tga_lcd_bg_g;
  19. extern uint8_t tga_lcd_bg_b;
  20. extern void tga_save_png(const char *name);
  21. struct _box_t
  22. {
  23. uint32_t w, h;
  24. };
  25. typedef struct _box_t box_t;
  26. struct _pos_t
  27. {
  28. uint32_t x, y;
  29. };
  30. typedef struct _pos_t pos_t;
  31. struct _pbox_t // placed box
  32. {
  33. pos_t pos;
  34. int box_idx;
  35. };
  36. typedef struct _pbox_t pbox_t;
  37. #define BOX_LIST_MAX 50
  38. box_t box_list[BOX_LIST_MAX];
  39. char box_word[BOX_LIST_MAX][64];
  40. const uint8_t *box_font[BOX_LIST_MAX];
  41. int box_cnt = 0;
  42. int box_index[BOX_LIST_MAX];
  43. #define PLACE_OPTION_MAX 100
  44. int place_option_cnt = 0;
  45. pos_t place_option_list[PLACE_OPTION_MAX];
  46. #define PLACED_BOX_MAX 100
  47. int placed_box_cnt = 0;
  48. pbox_t placed_box_list[PLACED_BOX_MAX];
  49. uint32_t placed_box_area_max_x;
  50. uint32_t placed_box_area_max_y;
  51. uint32_t placed_box_area_value;
  52. /*============================================*/
  53. int place_option_find(pos_t *p)
  54. {
  55. int i;
  56. for( i = 0; i < place_option_cnt; i++ )
  57. {
  58. if ( place_option_list[i].x == p->x && place_option_list[i].y == p->y)
  59. return i; // place option already exists
  60. }
  61. return -1;
  62. }
  63. void place_option_add(pos_t *p)
  64. {
  65. int i;
  66. assert(place_option_cnt < PLACE_OPTION_MAX);
  67. if ( place_option_find(p) >= 0 )
  68. return; // place option already exists
  69. // the placement option also must not be part of any existing box
  70. for( i = 2; i < placed_box_cnt; i++ )
  71. {
  72. if ( p->x >= placed_box_list[i].pos.x && p->x < placed_box_list[i].pos.x + box_list[placed_box_list[i].box_idx].w )
  73. if ( p->y >= placed_box_list[i].pos.y && p->y < placed_box_list[i].pos.y + box_list[placed_box_list[i].box_idx].h )
  74. return; // place option would be inside an existing box
  75. }
  76. // place option does not exist, add new place option
  77. place_option_list[place_option_cnt] = *p;
  78. place_option_cnt++;
  79. }
  80. void place_option_by_xy(uint32_t x, uint32_t y)
  81. {
  82. pos_t p;
  83. p.x = x;
  84. p.y = y;
  85. place_option_add(&p);
  86. }
  87. void place_option_delete(int idx)
  88. {
  89. if ( idx < 0 || idx >= place_option_cnt )
  90. return;
  91. for( ; idx+1 < place_option_cnt; idx++ )
  92. {
  93. place_option_list[idx] = place_option_list[idx+1];
  94. }
  95. place_option_cnt--;
  96. }
  97. /*============================================*/
  98. // p is copyied, b only the address is stored
  99. pbox_t *placed_box_push(pos_t *p, int box_idx)
  100. {
  101. assert(placed_box_cnt < PLACED_BOX_MAX);
  102. // place the new box
  103. placed_box_list[placed_box_cnt].pos = *p;
  104. placed_box_list[placed_box_cnt].box_idx = box_idx;
  105. placed_box_cnt++;
  106. return placed_box_list+placed_box_cnt-1;
  107. }
  108. void placed_box_pop(void)
  109. {
  110. assert(placed_box_cnt > 0);
  111. placed_box_cnt--;
  112. }
  113. uint32_t placed_box_calculate_max_area(void)
  114. {
  115. int i;
  116. placed_box_area_max_y = 0;
  117. placed_box_area_max_x = 0;
  118. for( i = 2; i < placed_box_cnt; i++ )
  119. {
  120. if ( placed_box_area_max_y < placed_box_list[i].pos.y + box_list[placed_box_list[i].box_idx].h )
  121. placed_box_area_max_y = placed_box_list[i].pos.y + box_list[placed_box_list[i].box_idx].h;
  122. if ( placed_box_area_max_x < placed_box_list[i].pos.x + box_list[placed_box_list[i].box_idx].w )
  123. placed_box_area_max_x = placed_box_list[i].pos.x + box_list[placed_box_list[i].box_idx].w;
  124. }
  125. if ( placed_box_area_max_x > WORD_CLOUD_MAX_X )
  126. // weight of y is higher, so this should give a more wider picture
  127. placed_box_area_value = placed_box_area_max_x*5 + placed_box_area_max_y ;
  128. else
  129. // weight of y is higher, so this should give a more wider picture
  130. placed_box_area_value = placed_box_area_max_x + placed_box_area_max_y *5;
  131. return placed_box_area_value;
  132. }
  133. /*============================================*/
  134. int is_intersection(pos_t *p1, box_t *b1, pos_t *p2, box_t *b2)
  135. {
  136. pos_t q1 = *p1;
  137. pos_t q2 = *p2;
  138. q1.x += b1->w;
  139. q1.y += b1->h;
  140. q2.x += b2->w;
  141. q2.y += b2->h;
  142. if ( p1->x >= q2.x || q1.x <= p2->x )
  143. return 0;
  144. if ( p1->y >= q2.y || q1.y <= p2->y )
  145. return 0;
  146. return 1;
  147. }
  148. int is_intersection_with_placed_box(pos_t *p1, box_t *b1, int idx)
  149. {
  150. return is_intersection(p1, b1, &(placed_box_list[idx].pos), box_list+placed_box_list[idx].box_idx );
  151. }
  152. int is_any_intersection(pos_t *p1, box_t *b1)
  153. {
  154. int i;
  155. // start with the third box, because the first two are boundary boxes
  156. for( i = 2; i < placed_box_cnt; i++ )
  157. {
  158. if ( is_intersection_with_placed_box(p1, b1, i) != 0 )
  159. return 1;
  160. }
  161. return 0;
  162. }
  163. // add new place options by a give pbox
  164. void place_option_by_pbox(pbox_t *pbox)
  165. {
  166. int i, found_i;
  167. uint32_t y, x;
  168. uint32_t max_y, max_x;
  169. // from the lower left corner, search towards the left until another box is hit.
  170. y = pbox->pos.y + box_list[pbox->box_idx].h;
  171. max_x = 0;
  172. found_i = -1;
  173. for( i = 0; i < placed_box_cnt; i++ )
  174. {
  175. if ( placed_box_list+i != pbox ) // do not check ourself
  176. {
  177. if ( placed_box_list[i].pos.x <= pbox->pos.x )
  178. {
  179. if ( y >= placed_box_list[i].pos.y && y < placed_box_list[i].pos.y + box_list[placed_box_list[i].box_idx].h )
  180. {
  181. // left box found, but is it max?
  182. // must use >= here, because the initial boxes have zero area
  183. if ( max_x <= placed_box_list[i].pos.x + box_list[placed_box_list[i].box_idx].w )
  184. {
  185. max_x = placed_box_list[i].pos.x + box_list[placed_box_list[i].box_idx].w;
  186. found_i = i;
  187. }
  188. }
  189. }
  190. }
  191. }
  192. if (found_i >= 0)
  193. place_option_by_xy(max_x, y);
  194. // from the upper right corner, search towards the top until another box is hit.
  195. x = pbox->pos.x + box_list[pbox->box_idx].w;
  196. max_y = 0;
  197. found_i = -1;
  198. for( i = 0; i < placed_box_cnt; i++ )
  199. {
  200. if ( placed_box_list+i != pbox ) // do not check ourself
  201. {
  202. if ( placed_box_list[i].pos.y <= pbox->pos.y )
  203. {
  204. if ( x >= placed_box_list[i].pos.x && x < placed_box_list[i].pos.x + box_list[placed_box_list[i].box_idx].w )
  205. {
  206. // upper box found, but is it the next ?
  207. // must use >= here, because the initial boxes have zero area
  208. if ( max_y <= placed_box_list[i].pos.y + box_list[placed_box_list[i].box_idx].h )
  209. {
  210. max_y = placed_box_list[i].pos.y + box_list[placed_box_list[i].box_idx].h;
  211. found_i = i;
  212. }
  213. }
  214. }
  215. }
  216. }
  217. if (found_i >= 0)
  218. place_option_by_xy(x, max_y);
  219. }
  220. void add_all_place_options(void)
  221. {
  222. int i;
  223. //place_option_cnt = 0; // clear the place option list
  224. for( i = 2; i < placed_box_cnt; i++ )
  225. {
  226. place_option_by_pbox(placed_box_list+i);
  227. }
  228. }
  229. void show(void)
  230. {
  231. pos_t p;
  232. box_t b;
  233. int i;
  234. b.w = 1;
  235. b.h = 1;
  236. for( p.y = 0; p.y < 30; p.y++ )
  237. {
  238. for( p.x = 0; p.x < 60; p.x++ )
  239. {
  240. for( i = 0; i < place_option_cnt; i++ )
  241. {
  242. if ( place_option_list[i].x == p.x && place_option_list[i].y == p.y )
  243. {
  244. break;
  245. }
  246. }
  247. if ( i < place_option_cnt )
  248. {
  249. printf("*");
  250. }
  251. else
  252. {
  253. for( i = 0; i < placed_box_cnt; i++ )
  254. {
  255. if ( is_intersection_with_placed_box(&p, &b, i) != 0 )
  256. break;
  257. }
  258. if ( i < placed_box_cnt )
  259. {
  260. printf("%c", i+'a');
  261. }
  262. else
  263. {
  264. printf(" ");
  265. }
  266. }
  267. }
  268. printf("\n");
  269. }
  270. }
  271. void init(void)
  272. {
  273. pos_t p;
  274. box_list[0].w = 0x0ffffffff;
  275. box_list[0].h = 0;
  276. box_list[1].w = 0;
  277. box_list[1].h = 0x0ffffffff;
  278. box_cnt = 2;
  279. p.x = 0;
  280. p.y = 0;
  281. placed_box_push(&p, 0);
  282. p.x = 0;
  283. p.y = 0;
  284. placed_box_push(&p, 1);
  285. // create one place option at the upper left
  286. place_option_by_xy(0, 0);
  287. }
  288. void do_best_place(int box_idx)
  289. {
  290. int i;
  291. int found_i;
  292. pbox_t *pbox;
  293. uint32_t value;
  294. uint32_t lowest_value;
  295. found_i = -1;
  296. lowest_value = 0x0ffffffff;
  297. for( i = 0; i < place_option_cnt; i++ )
  298. {
  299. // check whether this placement would generate an intersection
  300. if ( is_any_intersection(place_option_list+i, box_list+box_idx) == 0 )
  301. {
  302. // place the box at the position
  303. pbox = placed_box_push(place_option_list+i, box_idx);
  304. value = placed_box_calculate_max_area();
  305. /*
  306. if ( value == 0x0ffffffff )
  307. {
  308. value = pbox->pos.y;
  309. }
  310. else
  311. */
  312. {
  313. value *= 8;
  314. value += pbox->pos.x;
  315. value += pbox->pos.y;
  316. }
  317. // greedy algorithm: We search for the lowest area increase
  318. if ( lowest_value > value )
  319. {
  320. lowest_value = value ;
  321. found_i = i;
  322. }
  323. placed_box_pop();
  324. }
  325. }
  326. if ( found_i >= 0 )
  327. {
  328. // now permanently place the box
  329. pbox = placed_box_push(place_option_list+found_i, box_idx);
  330. // delete the position from the place option list
  331. place_option_delete(found_i);
  332. // calculate new place options with the new box
  333. //place_option_by_pbox(pbox);
  334. // recalculate all place options
  335. add_all_place_options();
  336. }
  337. else
  338. {
  339. assert(found_i >= 0 );
  340. }
  341. }
  342. /*
  343. Linear Congruential Generator (LCG)
  344. z = (a*z + c) % m;
  345. m = 256 (8 Bit)
  346. for period:
  347. a-1: dividable by 2
  348. a-1: multiple of 4
  349. c: not dividable by 2
  350. c = 17
  351. a-1 = 64 --> a = 65
  352. */
  353. uint8_t cloud_z = 127; // start value
  354. uint8_t cloud_rnd(void) {
  355. cloud_z = (uint8_t)((uint16_t)65*(uint16_t)cloud_z + (uint16_t)17);
  356. return (uint8_t)cloud_z;
  357. }
  358. //u8g2_IsAllValidUTF8
  359. char *cloud_utf8[] =
  360. {
  361. "µC"
  362. "Numérique"
  363. "像素",
  364. "屏幕",
  365. "图形",
  366. "Ψηφιακή",
  367. "Οθόνη",
  368. "Γραφικά",
  369. "アイコン、",
  370. "ビットマップ",
  371. "キャラクター、",
  372. "전자", "엔지니어", "장치", "하드웨어",
  373. "Ingeniør", "Skærm",
  374. "Gerät",
  375. "Sprzęt",
  376. "Računar", "Ugrađen",
  377. "Grafică",
  378. "экран",
  379. "Графика",
  380. "Значок",
  381. "Фонт", "екран", "рачунар", "уграђен",
  382. "พิกเซล",
  383. "หน้าจอ",
  384. "กราฟิก",
  385. "Gömülü",
  386. "ĂăĚěŇň",
  387. "ÄäÖöÜü",
  388. "Ææ",
  389. "E=mc²"
  390. };
  391. char *cloud_str[] =
  392. {
  393. "Pixel",
  394. "Screen",
  395. "Graphics",
  396. "Icon",
  397. "Bitmap",
  398. "Character",
  399. "Glyph",
  400. "Font",
  401. "Display",
  402. "Computer",
  403. "Embedded",
  404. "Electronics",
  405. "Engineer",
  406. "Device",
  407. "Hardware",
  408. "Software",
  409. "Science",
  410. "Digital",
  411. "Arduino",
  412. "U8g2"
  413. };
  414. char *cloud_simple[] =
  415. {
  416. "U8g2",
  417. "Abc",
  418. "XYZ",
  419. "Aa",
  420. "Xy"
  421. };
  422. void cloud_add(u8g2_t *u8g2, const uint8_t *font, char *word)
  423. {
  424. u8g2_uint_t extra = 8;
  425. u8g2_SetFont(u8g2, font);
  426. box_list[box_cnt].w = u8g2_GetUTF8Width(u8g2, word) + extra;
  427. box_list[box_cnt].h = u8g2_GetAscent(u8g2) - u8g2_GetDescent(u8g2) + extra;
  428. strcpy(box_word[box_cnt], word);
  429. //puts(word);
  430. box_font[box_cnt] = font;
  431. box_cnt++;
  432. }
  433. void cloud_auto_add(u8g2_t *u8g2, const uint8_t *font)
  434. {
  435. int i, n, cnt;
  436. u8g2_SetFont(u8g2, font);
  437. if ( u8g2_GetAscent(u8g2) - u8g2_GetDescent(u8g2) > 30 )
  438. {
  439. n = sizeof(cloud_simple)/sizeof(*cloud_simple);
  440. cnt = 0;
  441. for( i = 0; i < n; i++ )
  442. {
  443. if ( u8g2_IsAllValidUTF8(u8g2, cloud_simple[i]) != 0 )
  444. {
  445. cnt++;
  446. }
  447. }
  448. if ( cnt > 0 )
  449. {
  450. cnt = cloud_rnd() % cnt;
  451. for( i = 0; i < n; i++ )
  452. {
  453. if ( u8g2_IsAllValidUTF8(u8g2, cloud_simple[i]) != 0 )
  454. {
  455. if ( cnt == 0 )
  456. break;
  457. cnt--;
  458. }
  459. }
  460. }
  461. if ( i < n )
  462. {
  463. cloud_add(u8g2, font, cloud_simple[i]);
  464. return;
  465. }
  466. }
  467. n = sizeof(cloud_utf8)/sizeof(*cloud_utf8);
  468. //printf("n=%d\n", n);
  469. cnt = 0;
  470. for( i = 0; i < n; i++ )
  471. {
  472. if ( u8g2_IsAllValidUTF8(u8g2, cloud_utf8[i]) != 0 )
  473. {
  474. cnt++;
  475. }
  476. }
  477. if ( cnt > 0 )
  478. {
  479. cnt = cloud_rnd() % cnt;
  480. for( i = 0; i < n; i++ )
  481. {
  482. if ( u8g2_IsAllValidUTF8(u8g2, cloud_utf8[i]) != 0 )
  483. {
  484. if ( cnt == 0 )
  485. break;
  486. cnt--;
  487. }
  488. }
  489. }
  490. else
  491. {
  492. i = n;
  493. }
  494. if ( i < n )
  495. {
  496. cloud_add(u8g2, font, cloud_utf8[i]);
  497. return;
  498. }
  499. n = sizeof(cloud_str)/sizeof(*cloud_str);
  500. //printf("n=%d\n", n);
  501. i = cloud_rnd() % n;
  502. cloud_add(u8g2, font, cloud_str[i]);
  503. }
  504. void cloud_init(void)
  505. {
  506. init();
  507. }
  508. void cloud_calculate(uint8_t z)
  509. {
  510. int i;
  511. int a, b, t;
  512. cloud_z = z;
  513. for( i = 0; i < box_cnt; i++ )
  514. {
  515. box_index[i] = i;
  516. }
  517. for ( i = 0; i < box_cnt / 2; i++ )
  518. {
  519. a = cloud_rnd() % (box_cnt-2);
  520. a += 2;
  521. b = cloud_rnd() % (box_cnt-2);
  522. b += 2;
  523. t = box_index[a];
  524. box_index[a] = box_index[b];
  525. box_index[b] = t;
  526. }
  527. for( i = 2; i < box_cnt; i++ )
  528. do_best_place(box_index[i]);
  529. }
  530. void cloud_draw(u8g2_t *u8g2)
  531. {
  532. int i;
  533. for( i = 2; i < placed_box_cnt; i++ )
  534. {
  535. u8g2_SetFont(u8g2, box_font[placed_box_list[i].box_idx]);
  536. u8g2_DrawUTF8(u8g2,
  537. placed_box_list[i].pos.x,
  538. placed_box_list[i].pos.y,
  539. box_word[placed_box_list[i].box_idx]);
  540. }
  541. }
  542. u8g2_t u8g2;
  543. int main(void)
  544. {
  545. tga_desc_fg_r = 0;
  546. tga_desc_fg_g = 0;
  547. tga_desc_fg_b = 0;
  548. tga_desc_bg_r = 255;
  549. tga_desc_bg_g = 255;
  550. tga_desc_bg_b = 255;
  551. u8g2_SetupBuffer_TGA_DESC(&u8g2, &u8g2_cb_r0);
  552. u8x8_InitDisplay(u8g2_GetU8x8(&u8g2));
  553. u8x8_SetPowerSave(u8g2_GetU8x8(&u8g2), 0);
  554. u8g2_SetFont(&u8g2, u8g2_font_helvB18_tr);
  555. u8g2_SetFontPosTop(&u8g2);
  556. cloud_init();
  557. /*
  558. cloud_add(&u8g2, u8g2_font_helvR12_tr, "Embedded");
  559. cloud_add(&u8g2, u8g2_font_helvB12_tr, "Electronics");
  560. cloud_add(&u8g2, u8g2_font_helvR14_tr, "Arduino");
  561. cloud_add(&u8g2, u8g2_font_helvB14_tr, "Font");
  562. cloud_add(&u8g2, u8g2_font_helvR18_tr, "Controller");
  563. cloud_add(&u8g2, u8g2_font_helvB18_tr, "U8g2");
  564. cloud_add(&u8g2, u8g2_font_helvR24_tr, "ABC");
  565. cloud_add(&u8g2, u8g2_font_helvB24_tr, "XYZ");
  566. */
  567. cloud_auto_add(&u8g2, u8g2_font_helvR12_tr);
  568. cloud_auto_add(&u8g2, u8g2_font_helvB12_tr);
  569. cloud_auto_add(&u8g2, u8g2_font_helvR14_tr);
  570. cloud_auto_add(&u8g2, u8g2_font_helvB14_tr);
  571. cloud_auto_add(&u8g2, u8g2_font_helvR18_tr);
  572. cloud_auto_add(&u8g2, u8g2_font_helvB18_tr);
  573. cloud_auto_add(&u8g2, u8g2_font_gb16st_t_3);
  574. cloud_auto_add(&u8g2, u8g2_font_wqy12_t_gb2312);
  575. cloud_auto_add(&u8g2, u8g2_font_wqy14_t_gb2312);
  576. cloud_auto_add(&u8g2, u8g2_font_b10_t_japanese2);
  577. cloud_auto_add(&u8g2, u8g2_font_b16_b_t_japanese3);
  578. cloud_auto_add(&u8g2, u8g2_font_cu12_t_greek);
  579. cloud_auto_add(&u8g2, u8g2_font_cu12_t_cyrillic);
  580. cloud_auto_add(&u8g2, u8g2_font_unifont_t_korean2);
  581. cloud_auto_add(&u8g2, u8g2_font_unifont_t_polish);
  582. cloud_auto_add(&u8g2, u8g2_font_logisoso54_tf);
  583. cloud_auto_add(&u8g2, u8g2_font_gb16st_t_3);
  584. cloud_auto_add(&u8g2, u8g2_font_wqy12_t_gb2312);
  585. cloud_auto_add(&u8g2, u8g2_font_wqy14_t_gb2312);
  586. cloud_auto_add(&u8g2, u8g2_font_b10_t_japanese2);
  587. cloud_auto_add(&u8g2, u8g2_font_b16_b_t_japanese3);
  588. cloud_auto_add(&u8g2, u8g2_font_cu12_t_greek);
  589. cloud_auto_add(&u8g2, u8g2_font_cu12_t_cyrillic);
  590. cloud_auto_add(&u8g2, u8g2_font_unifont_t_korean2);
  591. cloud_auto_add(&u8g2, u8g2_font_unifont_t_polish);
  592. cloud_auto_add(&u8g2, u8g2_font_logisoso58_tf);
  593. cloud_calculate(4);
  594. u8g2_FirstPage(&u8g2);
  595. do
  596. {
  597. cloud_draw(&u8g2);
  598. /*
  599. u8g2_DrawFrame(&u8g2,
  600. placed_box_list[i].pos.x,
  601. placed_box_list[i].pos.y,
  602. box_list[placed_box_list[i].box_idx].w,
  603. box_list[placed_box_list[i].box_idx].h);
  604. */
  605. //u8g2_SetFont(&u8g2, u8g2_font_helvB18_tr);
  606. // u8g2_DrawStr(&u8g2, 20, 20, "abc");
  607. } while( u8g2_NextPage(&u8g2) );
  608. //tga_save("u8g2.tga");
  609. tga_save_png("u8g2.png");
  610. return 0;
  611. }