static Ret ftk_font_freetype_lookup (FtkFont* thiz, unsigned short code, FtkGlyph* glyph) { int index = 0; FT_Error err = 0; DECL_PRIV(thiz, priv); return_val_if_fail(thiz != NULL && glyph != NULL, RET_FAIL); index = FT_Get_Char_Index(priv->face, code); err = FT_Load_Glyph(priv->face, index, FT_LOAD_DEFAULT|FT_LOAD_RENDER); return_val_if_fail(err == 0, RET_FAIL); glyph->code = code; glyph->x = priv->face->glyph->bitmap_left; glyph->y = priv->face->glyph->bitmap_top; glyph->w = priv->face->glyph->bitmap.width; glyph->h = priv->face->glyph->bitmap.rows; glyph->advance_x = priv->face->glyph->advance.x >> 6; glyph->data = priv->face->glyph->bitmap.buffer; // For fix a bug-- the actual bitmap of some fonts is larger than it's font size if (glyph->h > thiz->height(thiz)) { ftk_logw("Bug font code: %04x\n", code); glyph->h = thiz->height(thiz); } return RET_OK; }
static Ret ftk_key_board_on_paint(FtkWidget* thiz) { size_t r = 0; size_t c = 0; size_t xoffset = 0; size_t yoffset = 0; DECL_PRIV0(thiz, priv); FtkKeyBoardView* view = NULL; FtkKeyBoardDesc* desc = priv->desc; FTK_BEGIN_PAINT(x, y, width, height, canvas); return_val_if_fail(desc != NULL && desc->view_nr > 0, RET_FAIL); ftk_canvas_reset_gc(canvas, ftk_widget_get_gc(thiz)); view = desc->views+desc->current_view; for(r = 0; r < view->row_nr; r++) { FtkKeyBoardRow* row = view->rows+r; for(c = 0; c < row->cell_nr; c++) { FtkKeyBoardCell* cell = row->cells+c; width = cell->width; height = row->height; yoffset = row->y + y; xoffset = cell->x + x; if(cell->action == NULL) { /*It is a spacer*/ continue; } /*Draw candidates */ if(cell->action == ftk_key_board_candidate_text) { size_t i = 0; size_t x_c = 0; size_t width_c = 0; FtkBitmap* bmp = cell->bg_normal; ftk_canvas_draw_bg_image(canvas, bmp, FTK_BG_FOUR_CORNER, xoffset, yoffset, width, height); for(i = desc->candidate_start; i < desc->candidate_nr; i++) { FtkKeyBoardCandidate* candidate = desc->candidates+i; size_t extent = candidate->extent; if((x_c + extent) > width) break; width_c = width - x_c; if(i == desc->candidate_focus) { size_t bg_width = (extent + 1) & 0xfffe; ftk_canvas_draw_bg_image(canvas, cell->bg_active, FTK_BG_FOUR_CORNER, xoffset + x_c, yoffset, bg_width, height); } ftk_canvas_draw_string(canvas, xoffset + x_c, yoffset + FTK_HALF(height), candidate->text, strlen(candidate->text), 1); x_c += candidate->extent + 1; bmp = desc->candidates_vertical_line; ftk_canvas_draw_bg_image(canvas, bmp, FTK_BG_NORMAL, xoffset + x_c, yoffset + 2, ftk_bitmap_width(bmp), height - 4); x_c += ftk_bitmap_width(bmp) + 1; } } else { FtkBitmap* bg = (cell == view->focus) ? cell->bg_active : cell->bg_normal; ftk_canvas_draw_bg_image(canvas, bg, FTK_BG_FOUR_CORNER, xoffset, yoffset, width, height); if(cell->icon != NULL) { ftk_canvas_draw_bg_image(canvas, cell->icon, FTK_BG_CENTER, xoffset, yoffset, width, height); } if(cell->text[0]) { size_t len = strlen(cell->text); size_t extent = ftk_canvas_get_extent(canvas, cell->text, len); if(extent <= width) { ftk_canvas_draw_string(canvas, xoffset + FTK_HALF(width - extent), yoffset + FTK_HALF(height), cell->text, len, 1); } else { ftk_logw("%s:%d %s is too long to show\n", __func__, __LINE__, cell->text); } } } } } FTK_END_PAINT(); }
static void ftk_key_board_desc_builder_on_start(FtkXmlBuilder* thiz, const char* tag, const char** attrs) { size_t i = 0; const char* key = NULL; const char* value = NULL; BuilderInfo* info = (BuilderInfo*)thiz->priv; FtkKeyBoardDesc* desc = info->desc; if(strcmp(tag, "keyboard") == 0) { for(i = 0; attrs[i] != NULL; i += 2) { key = attrs[i]; value = attrs[i+1]; if(strcmp(key, "min_width") == 0) { desc->min_width = ftk_atoi(value); } else if(strcmp(key, "min_height") == 0) { desc->min_height = ftk_atoi(value); } else if(strcmp(key, "views") == 0) { desc->view_nr = ftk_atoi(value); } else { ftk_logw("%s:%d unknown attr: %s\n", __func__, __LINE__, key); } } assert(desc->view_nr > 0); desc->current_view = 0; desc->views = (FtkKeyBoardView*)FTK_ZALLOC(desc->view_nr * sizeof(FtkKeyBoardView)); } else if(strcmp(tag, "view") == 0) { FtkKeyBoardView* view = desc->views + desc->current_view; for(i = 0; attrs[i] != NULL; i += 2) { key = attrs[i]; value = attrs[i+1]; if(strcmp(key, "rows") == 0) { view->row_nr = ftk_atoi(value); } else if(strcmp(key, "bg") == 0) { view->bg = ftk_theme_load_image(ftk_default_theme(), value); } else if(strcmp(key, "cell_bg_image[normal]") == 0) { view->cell_bg_normal = ftk_theme_load_image(ftk_default_theme(), value); } else if(strcmp(key, "cell_bg_image[active]") == 0) { view->cell_bg_active = ftk_theme_load_image(ftk_default_theme(), value); } else { ftk_logw("%s:%d unknown attr: %s\n", __func__, __LINE__, key); } } assert(view->row_nr > 0); view->current_row = 0; view->rows = (FtkKeyBoardRow*)FTK_ZALLOC(view->row_nr * sizeof(FtkKeyBoardRow)); } else if(strcmp(tag, "row") == 0) { FtkKeyBoardView* view = desc->views + desc->current_view; FtkKeyBoardRow* row = view->rows + view->current_row; for(i = 0; attrs[i] != NULL; i += 2) { key = attrs[i]; value = attrs[i+1]; if(strcmp(key, "cols") == 0) { row->cell_nr = ftk_atoi(value); } else if(strcmp(key, "height_weight") == 0) { row->height_weight = ftk_atoi(value); } else { ftk_logw("%s:%d unknown attr: %s\n", __func__, __LINE__, key); } } assert(row->cell_nr > 0); row->cells = (FtkKeyBoardCell*)FTK_ZALLOC(sizeof(FtkKeyBoardCell) * row->cell_nr); } else if(strcmp(tag, "spacer") == 0) { FtkKeyBoardView* view = desc->views + desc->current_view; FtkKeyBoardRow* row = view->rows + view->current_row; FtkKeyBoardCell* cell = row->cells + row->current_cell; for(i = 0; attrs[i] != NULL; i += 2) { key = attrs[i]; value = attrs[i+1]; if(strcmp(key, "width_weight") == 0) { cell->width_weight = ftk_atoi(value); } } } else if(strcmp(tag, "cell") == 0) { FtkKeyBoardView* view = desc->views + desc->current_view; FtkKeyBoardRow* row = view->rows + view->current_row; FtkKeyBoardCell* cell = row->cells + row->current_cell; for(i = 0; attrs[i] != NULL; i += 2) { key = attrs[i]; value = attrs[i+1]; if(strcmp(key, "text") == 0) { ftk_strncpy(cell->text, value, sizeof(cell->text)); } else if(strcmp(key, "action") == 0) { ftk_key_board_cell_init_action(cell, value); } else if(strcmp(key, "width_weight") == 0) { cell->width_weight = ftk_atoi(value); } else if(strcmp(key, "icon") == 0) { cell->icon = ftk_theme_load_image(ftk_default_theme(), value); } else if(strcmp(key, "bg_image[normal]") == 0) { cell->bg_normal = ftk_theme_load_image(ftk_default_theme(), value); } else if(strcmp(key, "bg_image[active]") == 0) { cell->bg_active = ftk_theme_load_image(ftk_default_theme(), value); } else { ftk_logw("%s:%d unknown attr: %s\n", __func__, __LINE__, key); } } if(cell->bg_normal == NULL) { cell->bg_normal = view->cell_bg_normal; ftk_bitmap_ref(cell->bg_normal); } if(cell->bg_active == NULL) { cell->bg_active = view->cell_bg_active; ftk_bitmap_ref(cell->bg_active); } } else { ftk_logw("%s:%d unknown tag: %s\n", __func__, __LINE__, tag); } return; }
static Ret ftk_key_board_cell_init_action(FtkKeyBoardCell* cell, const char* action_str) { char* p = NULL; char* args = NULL; char* action = ftk_strdup(action_str); return_val_if_fail(action != NULL, RET_FAIL); p = strrchr(action, ')'); return_val_if_fail(p != NULL, RET_FAIL); *p = '\0'; args = strchr(action, '('); return_val_if_fail(args != NULL, RET_FAIL); *args = '\0'; args += 1; ftk_strncpy(cell->action_str, action, sizeof(cell->action_str)); ftk_strncpy(cell->action_args, args, sizeof(cell->action_args)); if(strcmp(action, "send_key") == 0) { cell->action = ftk_key_board_send_key; } else if(strcmp(action, "switch_view") == 0) { cell->action = ftk_key_board_switch_view; } else if(strcmp(action, "choose_input_method") == 0) { cell->action = ftk_key_board_choose_input_method; } else if(strcmp(action, "call_custom") == 0) { cell->action = ftk_key_board_call_custom_action; } else if(strcmp(action, "candidate") == 0) { if(strcmp(args, "prev") == 0) { cell->action = ftk_key_board_candidate_prev; } else if(strcmp(args, "text") == 0) { cell->action = ftk_key_board_candidate_text; } else if(strcmp(args, "next") == 0) { cell->action = ftk_key_board_candidate_next; } else { assert(!"invalid args."); } } else { ftk_logw("%s:%d illegal action: %s\n", __func__, __LINE__, action_str); } FTK_FREE(action); return RET_OK; }