00001
00038 #include <assert.h>
00039 #include <string.h>
00040 #include <hugemem.h>
00041 #include <physmem.h>
00042 #include <status_codes.h>
00043
00044 #include <gfx/gfx.h>
00045 #include <gfx/win.h>
00046 #include <gfx/wtk.h>
00047 #include <gfx/sysfont.h>
00048
00049 #include "app_fonts.h"
00050 #include "app_desktop.h"
00051 #include "file_loader.h"
00052
00059
00060
00061
00062 #define FONT_HEADER_SIZE 16
00063
00064 #define NUMBER_OF_FONTS 4
00065
00066
00068
00069
00073 #define PAGE_NUM_BLANK_SCREEN 0
00074
00075 #define PAGE_NUM_MIN 1
00076
00077 #define PAGE_NUM_MAX 5
00078
00079
00081
00082
00083 #define COLOR_TEXT GFX_COLOR(255, 255, 255)
00084
00085 #define COLOR_TEXT_SHADED GFX_COLOR(150, 150, 150)
00086
00087 #define COLOR_BACKGROUND GFX_COLOR(0, 0, 0)
00088
00089 #define COLOR_FILL GFX_COLOR(48, 120, 158)
00090
00091 #define COLOR_FILL_BORDER GFX_COLOR(30, 74, 98)
00092
00093
00095
00096
00097 #define TEXT_INDENT 5
00098
00099 #define TEXT_PADDING 3
00100
00101 #define TEXT_PADDING_NEWLINE 2
00102
00103
00105 enum app_fonts_button_ids {
00107 BUTTON_NEXT_ID,
00109 BUTTON_PREV_ID,
00111 BUTTON_QUIT_ID,
00112 };
00113
00115 struct app_fonts {
00117 struct wtk_progress_bar *progress_bar;
00119 struct wtk_basic_frame *frame;
00121 struct workqueue_task task;
00123 struct gfx_bitmap background;
00125 struct wtk_button *btn_exit;
00127 struct wtk_button *btn_next;
00129 struct wtk_button *btn_prev;
00131 struct font *current_font_loading;
00133 struct font prev_sysfont;
00135 uint8_t page_number;
00136 };
00137
00139
00140
00141 static struct font font_ericat = {
00142 .type = FONT_LOC_HUGEMEM,
00143 .scale = 1,
00144 };
00145
00147 static struct font font_fixedrus = {
00148 .type = FONT_LOC_HUGEMEM,
00149 .scale = 1,
00150 };
00151
00153 static struct font font_larabie = {
00154 .type = FONT_LOC_HUGEMEM,
00155 .scale = 1,
00156 };
00157
00159 static struct font font_monofur = {
00160 .type = FONT_LOC_HUGEMEM,
00161 .scale = 1,
00162 };
00164
00166 static struct app_fonts *the_fonts_app;
00167
00179 static void draw_font_box(gfx_coord_t y, struct font *font, char *fontname)
00180 {
00181 gfx_coord_t height = (font->height * font->scale * 2) +
00182 TEXT_PADDING_NEWLINE + (2 * TEXT_PADDING);
00183
00184 gfx_draw_filled_rect(TEXT_PADDING, y, gfx_get_width() -
00185 (2 * TEXT_PADDING), height, COLOR_FILL);
00186 gfx_draw_rect(TEXT_PADDING, y, gfx_get_width() - (2 * TEXT_PADDING),
00187 height, COLOR_FILL_BORDER);
00188
00189 gfx_draw_string(fontname, (2 * TEXT_INDENT), y + TEXT_PADDING, font,
00190 COLOR_TEXT, GFX_COLOR_TRANSPARENT);
00191
00192 gfx_draw_string("The Quick Brown Fox Jumps Over the Lazy Dog",
00193 (2 * TEXT_INDENT), y + TEXT_PADDING +
00194 TEXT_PADDING_NEWLINE + (font->height * font->scale),
00195 font, COLOR_TEXT, GFX_COLOR_TRANSPARENT);
00196 }
00197
00203 static void screen_draw_splash(void)
00204 {
00205 gfx_draw_string(" Font and\r\nLanguage Support", 30, 60,
00206 &font_monofur, COLOR_TEXT,
00207 GFX_COLOR_TRANSPARENT);
00208 gfx_draw_string("- Ææ Øø Åå -", 95, 150, &font_ericat,
00209 COLOR_TEXT_SHADED, GFX_COLOR_TRANSPARENT);
00210 }
00211
00218 static void screen_draw_fonts_info(void)
00219 {
00220 gfx_coord_t y = TEXT_INDENT;
00221
00222 gfx_draw_horizontal_line(TEXT_PADDING, font_fixedrus.height *
00223 font_fixedrus.scale + TEXT_INDENT, gfx_get_width() -
00224 (2 * TEXT_PADDING), COLOR_FILL);
00225
00226 gfx_draw_string("Font Information", TEXT_INDENT, y, &font_fixedrus,
00227 COLOR_TEXT, GFX_COLOR_TRANSPARENT);
00228
00229 y += font_fixedrus.height + TEXT_INDENT;
00230
00231 gfx_draw_string("A powerful font system allows", TEXT_INDENT, y,
00232 &font_fixedrus, COLOR_TEXT, GFX_COLOR_TRANSPARENT);
00233
00234 y += font_fixedrus.height + TEXT_PADDING_NEWLINE;
00235
00236 gfx_draw_string("any number of fonts in use at", TEXT_INDENT, y,
00237 &font_fixedrus, COLOR_TEXT, GFX_COLOR_TRANSPARENT);
00238
00239 y += font_fixedrus.height + TEXT_PADDING_NEWLINE;
00240
00241 gfx_draw_string("the same time. This offers", TEXT_INDENT, y,
00242 &font_fixedrus, COLOR_TEXT, GFX_COLOR_TRANSPARENT);
00243
00244 y += font_fixedrus.height + TEXT_PADDING_NEWLINE;
00245
00246 gfx_draw_string("great flexibility in how text", TEXT_INDENT, y,
00247 &font_fixedrus, COLOR_TEXT, GFX_COLOR_TRANSPARENT);
00248
00249 y += font_fixedrus.height + TEXT_PADDING_NEWLINE;
00250
00251 gfx_draw_string("is presented to the user.", TEXT_INDENT, y,
00252 &font_fixedrus, COLOR_TEXT, GFX_COLOR_TRANSPARENT);
00253
00254 y += font_fixedrus.height + TEXT_INDENT;
00255
00256 gfx_draw_string("The next screen showcases some", TEXT_INDENT, y,
00257 &font_fixedrus, COLOR_TEXT, GFX_COLOR_TRANSPARENT);
00258
00259 y += font_fixedrus.height + TEXT_PADDING_NEWLINE;
00260
00261 gfx_draw_string( "of the fonts loaded in this", TEXT_INDENT, y,
00262 &font_fixedrus, COLOR_TEXT, GFX_COLOR_TRANSPARENT);
00263
00264 y += font_fixedrus.height + TEXT_PADDING_NEWLINE;
00265
00266 gfx_draw_string("application.", TEXT_INDENT, y, &font_fixedrus,
00267 COLOR_TEXT, GFX_COLOR_TRANSPARENT);
00268 }
00269
00276 static void screen_draw_fonts_list(void)
00277 {
00278 gfx_coord_t y = TEXT_PADDING;
00279
00280 draw_font_box(y, &font_monofur, "Monofur");
00281 y += (2 * font_monofur.height * font_monofur.scale) +
00282 (3 * TEXT_PADDING) + TEXT_PADDING_NEWLINE;
00283 draw_font_box(y, &sysfont, "System Font");
00284 y += (2 * sysfont.height * sysfont.scale) + (3 * TEXT_PADDING)
00285 + TEXT_PADDING_NEWLINE;
00286 draw_font_box(y, &font_ericat, "Erica Type");
00287 y += (2 * font_ericat.height * font_ericat.scale) +
00288 (3 * TEXT_PADDING) + TEXT_PADDING_NEWLINE;
00289 draw_font_box(y, &font_fixedrus, "Fixedsys");
00290 }
00291
00298 static void screen_draw_language_info(void)
00299 {
00300 gfx_coord_t y = TEXT_INDENT;
00301
00302 gfx_draw_horizontal_line(TEXT_PADDING, font_fixedrus.height *
00303 font_fixedrus.scale + TEXT_INDENT, gfx_get_width() -
00304 (2 * TEXT_PADDING), COLOR_FILL);
00305
00306 gfx_draw_string("Language Information", TEXT_INDENT, y, &font_fixedrus,
00307 COLOR_TEXT, GFX_COLOR_TRANSPARENT);
00308
00309 y += font_fixedrus.height + (2 * TEXT_PADDING_NEWLINE);
00310
00311 gfx_draw_string("Full Extended ASCII support", TEXT_INDENT, y,
00312 &font_fixedrus, COLOR_TEXT, GFX_COLOR_TRANSPARENT);
00313
00314 y += font_fixedrus.height + TEXT_PADDING_NEWLINE;
00315
00316 gfx_draw_string("makes it easy to switch", TEXT_INDENT, y,
00317 &font_fixedrus, COLOR_TEXT, GFX_COLOR_TRANSPARENT);
00318
00319 y += font_fixedrus.height + TEXT_PADDING_NEWLINE;
00320
00321 gfx_draw_string("between local character sets ", TEXT_INDENT, y,
00322 &font_fixedrus, COLOR_TEXT, GFX_COLOR_TRANSPARENT);
00323
00324 y += font_fixedrus.height + TEXT_PADDING_NEWLINE;
00325
00326 gfx_draw_string("and print text in different", TEXT_INDENT, y,
00327 &font_fixedrus, COLOR_TEXT, GFX_COLOR_TRANSPARENT);
00328
00329 y += font_fixedrus.height + TEXT_PADDING_NEWLINE;
00330
00331 gfx_draw_string("languages, fonts or sizes.", TEXT_INDENT, y,
00332 &font_fixedrus, COLOR_TEXT, GFX_COLOR_TRANSPARENT);
00333 }
00334
00342 static void screen_draw_messages(void)
00343 {
00344
00345 gfx_draw_string("È un piacere conoscerla", 40, 5, &font_ericat,
00346 COLOR_TEXT, GFX_COLOR_TRANSPARENT);
00347
00348
00349 gfx_draw_string("Guten Tag! Wie geht's?", 5, 30, &sysfont, COLOR_TEXT,
00350 GFX_COLOR_TRANSPARENT);
00351
00352
00353 gfx_draw_string("Hello and welcome!", 105, 50, &font_fixedrus,
00354 COLOR_TEXT, GFX_COLOR_TRANSPARENT);
00355
00356
00357 gfx_draw_string("Hyggelig å møtes!", 41, 70, &font_monofur, COLOR_TEXT,
00358 GFX_COLOR_TRANSPARENT);
00359
00360
00361 gfx_draw_string("Jetez un coup d'œil,\r\ns'il vous plaît!", 10, 110,
00362 &font_ericat, COLOR_TEXT, GFX_COLOR_TRANSPARENT);
00363
00364
00365 gfx_draw_string("¿Podría Ayudarse?", 150, 155, &font_larabie,
00366 COLOR_TEXT, GFX_COLOR_TRANSPARENT);
00367
00368
00369 gfx_draw_string("Grüß Gott!", 80, 170, &font_monofur, COLOR_TEXT,
00370 GFX_COLOR_TRANSPARENT);
00371
00372
00373 gfx_draw_string("\xC1\xF3\xC4\xE5\xEC \xE7\xC4\xEE\xF0\xEE\xE2\xDB!",
00374 30, 210, &font_fixedrus, COLOR_TEXT,
00375 GFX_COLOR_TRANSPARENT);
00376 }
00377
00389 static void app_fonts_frame_draw_handler(struct win_window *win,
00390 const struct win_clip_region *clip)
00391 {
00392 switch (the_fonts_app->page_number) {
00393 case PAGE_NUM_BLANK_SCREEN:
00394 break;
00395
00396 case 1:
00397 screen_draw_splash();
00398 break;
00399
00400 case 2:
00401 screen_draw_fonts_info();
00402 break;
00403
00404 case 3:
00405 screen_draw_fonts_list();
00406 break;
00407
00408 case 4:
00409 screen_draw_language_info();
00410 break;
00411
00412 case 5:
00413 screen_draw_messages();
00414 break;
00415
00416 default:
00417
00418 unhandled_case(the_fonts_app->page_number);
00419 break;
00420 }
00421 }
00422
00436 static bool app_fonts_frame_command_handler(struct wtk_basic_frame *frame,
00437 win_command_t command_data)
00438 {
00439 uint8_t command = (uint8_t)(uintptr_t)command_data;
00440
00441 switch (command) {
00442 case BUTTON_NEXT_ID:
00443
00444 the_fonts_app->page_number++;
00445 if (the_fonts_app->page_number > PAGE_NUM_MAX)
00446 the_fonts_app->page_number = PAGE_NUM_MIN;
00447 win_redraw(wtk_basic_frame_as_child(the_fonts_app->frame));
00448 break;
00449
00450 case BUTTON_PREV_ID:
00451
00452 the_fonts_app->page_number--;
00453 if (the_fonts_app->page_number < PAGE_NUM_MIN)
00454 the_fonts_app->page_number = PAGE_NUM_MAX;
00455 win_redraw(wtk_basic_frame_as_child(the_fonts_app->frame));
00456 break;
00457
00458 case BUTTON_QUIT_ID:
00459
00460 memcpy(&sysfont, &the_fonts_app->prev_sysfont,
00461 sizeof(struct font));
00462 membag_free(the_fonts_app);
00463 app_desktop_restart();
00464 return true;
00465
00466 default:
00467 break;
00468 }
00469
00470 return false;
00471 }
00472
00473 static status_t app_fonts_load(void);
00474
00487 static void app_fonts_load_worker(struct workqueue_task *task)
00488 {
00489 status_t retval;
00490
00491 if (the_fonts_app->current_font_loading) {
00492 struct font *font = the_fonts_app->current_font_loading;
00493 uint8_t buffer[FONT_HEADER_SIZE];
00494
00495 the_fonts_app->current_font_loading = NULL;
00496
00497 hugemem_read_block(buffer, font->data.hugemem,
00498 FONT_HEADER_SIZE);
00499
00500 assert(buffer[0] == 'F' && buffer[1] == 'T');
00501
00502 font->width = buffer[2];
00503 font->height = buffer[3];
00504 font->first_char = buffer[4];
00505 font->last_char = buffer[5];
00506 font->data.hugemem = (hugemem_ptr_t)
00507 ((uint32_t)font->data.hugemem + FONT_HEADER_SIZE);
00508 }
00509
00510 retval = app_fonts_load();
00511 if (retval == STATUS_OK) {
00512
00513
00514
00515
00516 the_fonts_app->page_number = PAGE_NUM_MIN;
00517 win_redraw(wtk_basic_frame_as_child(the_fonts_app->frame));
00518 win_show(wtk_button_as_child(the_fonts_app->btn_exit));
00519 win_show(wtk_button_as_child(the_fonts_app->btn_next));
00520 win_show(wtk_button_as_child(the_fonts_app->btn_prev));
00521 }
00522 else if (retval == ERR_BUSY) {
00523
00524 } else {
00525
00526
00527
00528
00529 win_destroy(wtk_basic_frame_as_child(the_fonts_app->frame));
00530 memcpy(&sysfont, &the_fonts_app->prev_sysfont,
00531 sizeof(struct font));
00532 membag_free(the_fonts_app);
00533 app_desktop_restart();
00534 }
00535 }
00536
00548 static status_t app_fonts_load(void)
00549 {
00550 hugemem_ptr_t addr;
00551
00552
00553 if (!font_ericat.data.hugemem) {
00554 addr = load_file_to_hugemem("f_ericat", &the_fonts_app->task);
00555 if (addr == HUGEMEM_NULL)
00556 return ERR_IO_ERROR;
00557
00558 font_ericat.data.hugemem = addr;
00559 the_fonts_app->current_font_loading = &font_ericat;
00560 wtk_progress_bar_set_value(the_fonts_app->progress_bar, 1);
00561 return ERR_BUSY;
00562 }
00563
00564 if (!font_fixedrus.data.hugemem) {
00565 addr = load_file_to_hugemem("f_fixrus", &the_fonts_app->task);
00566 if (addr == HUGEMEM_NULL)
00567 return ERR_IO_ERROR;
00568
00569 font_fixedrus.data.hugemem = addr;
00570 the_fonts_app->current_font_loading = &font_fixedrus;
00571 wtk_progress_bar_set_value(the_fonts_app->progress_bar, 2);
00572
00573 return ERR_BUSY;
00574 }
00575
00576 if (!font_larabie.data.hugemem) {
00577 addr = load_file_to_hugemem("f_larab", &the_fonts_app->task);
00578 if (addr == HUGEMEM_NULL)
00579 return ERR_IO_ERROR;
00580
00581 font_larabie.data.hugemem = addr;
00582 the_fonts_app->current_font_loading = &font_larabie;
00583 wtk_progress_bar_set_value(the_fonts_app->progress_bar, 3);
00584
00585 return ERR_BUSY;
00586 }
00587
00588 if (!font_monofur.data.hugemem) {
00589 addr = load_file_to_hugemem("f_monfur", &the_fonts_app->task);
00590 if (addr == HUGEMEM_NULL)
00591 return ERR_IO_ERROR;
00592
00593 font_monofur.data.hugemem = addr;
00594 the_fonts_app->current_font_loading = &font_monofur;
00595 wtk_progress_bar_set_value(the_fonts_app->progress_bar, 4);
00596
00597 return ERR_BUSY;
00598 }
00599
00600
00601
00602
00603
00604
00605 win_destroy(wtk_progress_bar_as_child(the_fonts_app->progress_bar));
00606
00607 return STATUS_OK;
00608 }
00609
00619 void app_fonts_launch(struct workqueue_task *task)
00620 {
00621 struct win_window *win_root;
00622 struct win_window *parent;
00623 struct win_area area;
00624 status_t retval;
00625
00626 the_fonts_app = membag_alloc(sizeof(struct app_fonts));
00627 if (!the_fonts_app)
00628 goto error_membag_alloc;
00629
00630
00631 the_fonts_app->page_number = PAGE_NUM_BLANK_SCREEN;
00632
00633
00634 memcpy(&the_fonts_app->prev_sysfont, &sysfont, sizeof(struct font));
00635 sysfont.scale = 2;
00636
00637
00638
00639
00640
00641 workqueue_task_init(&the_fonts_app->task, app_fonts_load_worker);
00642
00643
00644
00645
00646
00647
00648
00649 the_fonts_app->background.type = BITMAP_SOLID;
00650 the_fonts_app->background.data.color = COLOR_BACKGROUND;
00651
00652 win_root = win_get_root();
00653
00654
00655
00656
00657
00658 area.pos.x = 0;
00659 area.pos.y = 0;
00660 area.size.x = gfx_get_width();
00661 area.size.y = gfx_get_height();
00662
00663 the_fonts_app->frame = wtk_basic_frame_create(win_root, &area,
00664 &the_fonts_app->background,
00665 app_fonts_frame_draw_handler,
00666 app_fonts_frame_command_handler, &the_fonts_app);
00667 if (!the_fonts_app->frame)
00668 goto error_text_frame;
00669
00670 parent = wtk_basic_frame_as_child(the_fonts_app->frame);
00671 win_show(parent);
00672
00673
00674 area.size.x = APP_EXIT_BUTTON_SIZE_X;
00675 area.size.y = APP_EXIT_BUTTON_SIZE_Y;
00676 area.pos.x = APP_EXIT_BUTTON_POS_X;
00677 area.pos.y = APP_EXIT_BUTTON_POS_Y;
00678
00679 the_fonts_app->btn_exit = wtk_button_create(parent, &area,
00680 APP_EXIT_BUTTON_TEXT, (win_command_t)BUTTON_QUIT_ID);
00681 if (!the_fonts_app->btn_exit)
00682 goto error_widget;
00683
00684
00685 area.pos.x -= APP_EXIT_BUTTON_SIZE_X;
00686
00687 the_fonts_app->btn_next = wtk_button_create(parent, &area, ">>",
00688 (win_command_t)BUTTON_NEXT_ID);
00689 if (!the_fonts_app->btn_next)
00690 goto error_widget;
00691
00692
00693 area.pos.x -= APP_EXIT_BUTTON_SIZE_X;
00694
00695 the_fonts_app->btn_prev = wtk_button_create(parent, &area, "<<",
00696 (win_command_t)BUTTON_PREV_ID);
00697 if (!the_fonts_app->btn_prev)
00698 goto error_widget;
00699
00700
00701 area.pos.x = 0;
00702 area.size.x = gfx_get_width() - (3 * APP_EXIT_BUTTON_SIZE_X);
00703
00704 the_fonts_app->progress_bar = wtk_progress_bar_create(parent, &area,
00705 NUMBER_OF_FONTS, 0, COLOR_FILL, COLOR_BACKGROUND,
00706 WTK_PROGRESS_BAR_HORIZONTAL);
00707 if (!the_fonts_app->progress_bar)
00708 goto error_widget;
00709
00710 win_show(wtk_progress_bar_as_child(the_fonts_app->progress_bar));
00711
00712
00713
00714
00715
00716
00717
00718 retval = app_fonts_load();
00719 if (retval == STATUS_OK) {
00720 the_fonts_app->page_number = PAGE_NUM_MIN;
00721 win_redraw(parent);
00722 win_show(wtk_button_as_child(the_fonts_app->btn_exit));
00723 win_show(wtk_button_as_child(the_fonts_app->btn_next));
00724 win_show(wtk_button_as_child(the_fonts_app->btn_prev));
00725 }
00726 else if (retval != ERR_BUSY) {
00727 goto error_widget;
00728 }
00729
00730 return;
00731
00732 error_widget:
00733 win_destroy(parent);
00734 error_text_frame:
00735 memcpy(&sysfont, &the_fonts_app->prev_sysfont, sizeof(struct font));
00736 membag_free(the_fonts_app);
00737 error_membag_alloc:
00738 app_desktop_restart();
00739 }
00740