static int bb_render_glyph(void *backend_data, drawctx_t *context, source_t *source, sysarg_t ox, sysarg_t oy, glyph_id_t glyph_id) { bitmap_backend_data_t *data = (bitmap_backend_data_t *) backend_data; glyph_metrics_t glyph_metrics; int rc = bb_get_glyph_metrics(backend_data, glyph_id, &glyph_metrics); if (rc != EOK) return rc; surface_t *glyph_surface; rc = get_glyph_surface(data, glyph_id, &glyph_surface); if (rc != EOK) return rc; native_t x = ox + glyph_metrics.left_side_bearing; native_t y = oy - glyph_metrics.ascender; transform_t transform; transform_identity(&transform); transform_translate(&transform, x, y); source_set_transform(source, transform); source_set_mask(source, glyph_surface, false); drawctx_transfer(context, x, y, glyph_metrics.width, glyph_metrics.height); return EOK; }
static int get_glyph_surface(bitmap_backend_data_t *data, glyph_id_t glyph_id, surface_t **result) { if (glyph_id >= data->glyph_count) return ENOENT; if (data->glyph_cache[glyph_id].surface != NULL) { *result = data->glyph_cache[glyph_id].surface; return EOK; } surface_t *raw_surface; int rc = data->decoder->load_glyph_surface(data->decoder_data, glyph_id, &raw_surface); if (rc != EOK) return rc; sysarg_t w; sysarg_t h; surface_get_resolution(raw_surface, &w, &h); if (!data->scale) { *result = raw_surface; return EOK; } source_t source; source_init(&source); source_set_texture(&source, raw_surface, PIXELMAP_EXTEND_TRANSPARENT_BLACK); transform_t transform; transform_identity(&transform); transform_translate(&transform, 0.5, 0.5); transform_scale(&transform, data->scale_ratio, data->scale_ratio); source_set_transform(&source, transform); surface_coord_t scaled_width = (data->scale_ratio * ((double) w) + 0.5); surface_coord_t scaled_height = (data->scale_ratio * ((double) h) + 0.5); surface_t *scaled_surface = surface_create(scaled_width, scaled_height, NULL, 0); if (!scaled_surface) { surface_destroy(raw_surface); return ENOMEM; } drawctx_t context; drawctx_init(&context, scaled_surface); drawctx_set_source(&context, &source); drawctx_transfer(&context, 0, 0, scaled_width, scaled_height); surface_destroy(raw_surface); data->glyph_cache[glyph_id].surface = scaled_surface; *result = scaled_surface; return EOK; }
static void paint_internal(widget_t *w) { button_t *btn = (button_t *) w; surface_t *surface = window_claim(btn->widget.window); if (!surface) { window_yield(btn->widget.window); } drawctx_t drawctx; drawctx_init(&drawctx, surface); drawctx_set_source(&drawctx, &btn->foreground); drawctx_transfer(&drawctx, w->hpos, w->vpos, w->width, w->height); if (w->width >= 6 && w->height >= 6) { drawctx_set_source(&drawctx, &btn->background); drawctx_transfer(&drawctx, w->hpos + 3, w->vpos + 3, w->width - 6, w->height - 6); } sysarg_t cpt_width; sysarg_t cpt_height; font_get_box(&btn->font, btn->caption, &cpt_width, &cpt_height); if (w->width >= cpt_width && w->height >= cpt_height) { drawctx_set_source(&drawctx, &btn->foreground); drawctx_set_font(&drawctx, &btn->font); sysarg_t x = ((w->width - cpt_width) / 2) + w->hpos; sysarg_t y = ((w->height - cpt_height) / 2) + w->vpos; if (btn->caption) { drawctx_print(&drawctx, btn->caption, x, y); } } window_yield(btn->widget.window); }