void surface_create_from_data(surface *sur, int type, int w, int h, const char *src) { surface_create(sur, type, w, h); int size = w * h * ((type == SURFACE_TYPE_PALETTE) ? 1 : 4); memcpy(sur->data, src, size); if(type == SURFACE_TYPE_PALETTE) { memset(sur->stencil, 1, w * h); } }
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 cairo_test_status_t draw (cairo_t *cr, int width, int height) { cairo_surface_t *surface; cairo_translate (cr, PAD, PAD); cairo_save (cr); /* Draw overlapping circle and fallback circle */ cairo_set_source_rgb (cr, 0.0, 1.0, 0.0); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); draw_circle (cr, CIRCLE_SIZE*0.5, CIRCLE_SIZE*1.5); cairo_set_source_rgb (cr, 1.0, 0.0, 0.0); cairo_set_operator (cr, CAIRO_OPERATOR_ADD); draw_circle (cr, CIRCLE_SIZE*0.75, CIRCLE_SIZE*1.75); /* Draw circles */ cairo_set_source_rgb (cr, 0.0, 1.0, 0.0); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); cairo_translate (cr, CIRCLE_SIZE*2.5, CIRCLE_SIZE*0.6); draw_circles (cr); /* Draw fallback circles */ cairo_set_source_rgb (cr, 1.0, 0.0, 0.0); cairo_set_operator (cr, CAIRO_OPERATOR_ADD); cairo_translate (cr, 0, CIRCLE_SIZE*2); draw_circles (cr); cairo_restore (cr); cairo_translate (cr, 0, CIRCLE_SIZE * 3.5); /* Draw using fallback surface */ surface = surface_create (cr); cairo_set_source_rgb (cr, 0.0, 1.0, 0.0); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); draw_circle (cr, CIRCLE_SIZE*0.5, CIRCLE_SIZE*1.5); cairo_set_operator (cr, CAIRO_OPERATOR_ADD); draw_image_circle (cr, surface, CIRCLE_SIZE/4, CIRCLE_SIZE + CIRCLE_SIZE/4); /* Draw circles */ cairo_set_source_rgb (cr, 0.0, 1.0, 0.0); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); cairo_translate (cr, CIRCLE_SIZE*2.5, CIRCLE_SIZE*0.6); draw_circles (cr); cairo_set_operator (cr, CAIRO_OPERATOR_ADD); cairo_translate (cr, -CIRCLE_SIZE/2, CIRCLE_SIZE*1.5); draw_image_circles (cr, surface); cairo_surface_destroy (surface); return CAIRO_TEST_SUCCESS; }
// Copies a surface to a new surface // Note! New surface will be created here; there is no need to pre-create it void surface_copy(surface *dst, surface *src) { surface_create(dst, src->type, src->w, src->h); int size = src->w * src->h * ((src->type == SURFACE_TYPE_PALETTE) ? 1 : 4); memcpy(dst->data, src->data, size); if(src->stencil != NULL && dst->stencil != NULL) { memcpy(dst->stencil, src->stencil, src->w * src->h); } else { dst->stencil = NULL; } }
pixman_image_t *surface_create_stride(pixman_format_code_t format, int width, int height, int stride) #endif { #ifdef WIN32 if (dc) { if (abs(stride) == (width * 4)) { return surface_create(dc, format, width, height, (stride > 0)); } } #endif return __surface_create_stride(format, width, height, stride); }
static int client_main(void) { struct client_test client; client_test_create(&client, "fullscreen", 320, 320); surface_create(&client); shell_surface_create(&client); client_test_roundtrip(&client); client_test_roundtrip(&client); struct output *o; assert((o = chck_iter_pool_get(&client.outputs, 0))); wl_shell_surface_set_fullscreen(client.view.ssurface, 0, 0, o->output); wl_surface_commit(client.view.surface); while (wl_display_dispatch(client.display) != -1); return client_test_end(&client); }
static int fde_load_glyph_surface(void *unused, glyph_id_t glyph_id, surface_t **out_surface) { surface_t *surface = surface_create(FONT_WIDTH, FONT_SCANLINES, NULL, 0); if (!surface) return ENOMEM; for (unsigned int y = 0; y < FONT_SCANLINES; ++y) { for (unsigned int x = 0; x < FONT_WIDTH; ++x) { pixel_t p = (fb_font[glyph_id][y] & (1 << (7 - x))) ? PIXEL(255, 0, 0, 0) : PIXEL(0, 0, 0, 0); surface_put_pixel(surface, x, y, p); } } *out_surface = surface; return EOK; }
int scoreboard_create(scene *scene) { // Init local data scoreboard_local *local = malloc(sizeof(scoreboard_local)); local->page = settings_get()->gameplay.rounds; // Load scores if(scores_read(&local->data) == 1) { scores_clear(&local->data); DEBUG("No score data found; using empty score array."); } // Check for pending score local->has_pending_data = 0; if(found_pending_score(scene)) { game_player *player = game_state_get_player(scene->gs, 0); unsigned int score = player->score.score; if(score_fits_scoreboard(local, score)) { local->has_pending_data = 1; local->pending_data.score = score; local->pending_data.har_id = player->har_id; local->pending_data.pilot_id = player->pilot_id; local->pending_data.name[0] = 0; } // Wipe old score data, whether it was written on scoreboard or not. chr_score_reset(game_player_get_score(player), 1); } // Create a surface that has an appropriate alpha for darkening the screen a bit surface_create(&local->black_surface, SURFACE_TYPE_RGBA, 32, 32); surface_fill(&local->black_surface, color_create(0,0,0,200)); // Set callbacks scene_set_userdata(scene, local); scene_set_event_cb(scene, scoreboard_event); scene_set_input_poll_cb(scene, scoreboard_input_tick); scene_set_render_overlay_cb(scene, scoreboard_render_overlay); scene_set_free_cb(scene, scoreboard_free); video_select_renderer(VIDEO_RENDERER_HW); // All done return 0; }
int video_area_capture(surface *sur, int x, int y, int w, int h) { float scale_x = (float)state.w / NATIVE_W; float scale_y = (float)state.h / NATIVE_H; // Correct position (take scaling into account) SDL_Rect r; r.x = x * scale_x; r.y = y * scale_y; r.w = w * scale_x; r.h = h * scale_y; // Create a new surface surface_create(sur, SURFACE_TYPE_RGBA, r.w, r.h); // Read pixels int ret = SDL_RenderReadPixels(state.renderer, &r, SDL_PIXELFORMAT_ABGR8888, sur->data, sur->w * 4); if(ret != 0) { surface_free(sur); PERROR("Unable to read pixels from renderer: %s", SDL_GetError()); return 1; } return 0; }
SDL_Texture* tcache_get(surface *sur, screen_palette *pal, char *remap_table, uint8_t pal_offset) { if(sur == NULL || sur->w == 0 || sur->h == 0 || sur->data == NULL) { if(sur != NULL) { DEBUG("Invalid surface requested from tcache: w,h = %d,%d data = %p", sur->w, sur->h, sur->data); } else { DEBUG("Invalid surface requested from tcache: w,h = %d,%d surface = %p", sur->w, sur->h, sur); } return NULL; } // Form a key tcache_entry_key key; memset(&key, 0, sizeof(tcache_entry_key)); key.c_pal_offset = (sur->type == SURFACE_TYPE_RGBA) ? 0 : pal_offset; key.c_remap_table = (sur->type == SURFACE_TYPE_RGBA) ? 0 : remap_table; key.c_surface = sur; key.w = sur->w; key.h = sur->h; // Attempt to find appropriate surface // If surface is cacheable and hasn't changed, just return here. tcache_entry_value *val = tcache_get_entry(&key); if(val != NULL && (val->pal_version == pal->version || sur->type == SURFACE_TYPE_RGBA) && !sur->force_refresh) { val->age = 0; cache->hits++; return val->tex; } // Reset refresh flag here sur->force_refresh = 0; // If there was no fitting surface tex in the cache at all, // then we need to create one if(val == NULL) { tcache_entry_value new_entry; new_entry.age = 0; new_entry.pal_version = pal->version; new_entry.tex = SDL_CreateTexture(cache->renderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STREAMING, sur->w * cache->scale_factor, sur->h * cache->scale_factor); SDL_SetTextureBlendMode(new_entry.tex, SDL_BLENDMODE_BLEND); val = tcache_add_entry(&key, &new_entry); } // We have a texture either from the cache, or we just created one. // Either one, it needs to be updated. Let's do it now. // Also, scale surface if necessary if(cache->scale_factor > 1) { char *raw = malloc(sur->w * sur->h * 4); surface scaled; surface_create(&scaled, SURFACE_TYPE_RGBA, sur->w * cache->scale_factor, sur->h * cache->scale_factor); surface_to_rgba(sur, raw, pal, remap_table, pal_offset); scaler_scale(cache->scaler, raw, scaled.data, sur->w, sur->h, cache->scale_factor); surface_to_texture(&scaled, val->tex, pal, remap_table, pal_offset); surface_free(&scaled); free(raw); } else { surface_to_texture(sur, val->tex, pal, remap_table, pal_offset); } // Set correct age and palette version val->age = 0; val->pal_version = pal->version; // Do some statistics stuff cache->misses++; return val->tex; }
int main(int argc, char *argv[]) { long dt; long started; XWindow xw; struct demo_gui gui; /* Platform */ UNUSED(argc); UNUSED(argv); memset(&xw, 0, sizeof xw); xw.dpy = XOpenDisplay(NULL); xw.root = DefaultRootWindow(xw.dpy); xw.screen = XDefaultScreen(xw.dpy); xw.vis = XDefaultVisual(xw.dpy, xw.screen); xw.cmap = XCreateColormap(xw.dpy,xw.root,xw.vis,AllocNone); xw.swa.colormap = xw.cmap; xw.swa.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPress | ButtonReleaseMask| ButtonMotionMask | Button1MotionMask | Button3MotionMask | Button4MotionMask | Button5MotionMask| PointerMotionMask; xw.win = XCreateWindow(xw.dpy, xw.root, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, 0, XDefaultDepth(xw.dpy, xw.screen), InputOutput, xw.vis, CWEventMask | CWColormap, &xw.swa); XStoreName(xw.dpy, xw.win, "X11"); XMapWindow(xw.dpy, xw.win); XGetWindowAttributes(xw.dpy, xw.win, &xw.attr); xw.width = (unsigned int)xw.attr.width; xw.height = (unsigned int)xw.attr.height; xw.surf = surface_create(xw.dpy, xw.screen, xw.win, xw.width, xw.height); xw.font = font_create(xw.dpy, "fixed"); /* GUI */ memset(&gui, 0, sizeof gui); zr_command_queue_init_fixed(&gui.queue, calloc(MAX_MEMORY, 1), MAX_MEMORY); gui.font.userdata = zr_handle_ptr(xw.font); gui.font.height = (zr_float)xw.font->height; gui.font.width = font_get_text_width; init_demo(&gui); while (gui.running) { /* Input */ XEvent evt; started = timestamp(); zr_input_begin(&gui.input); while (XCheckWindowEvent(xw.dpy, xw.win, xw.swa.event_mask, &evt)) { if (evt.type == KeyPress) key(&xw, &gui.input, &evt, zr_true); else if (evt.type == KeyRelease) key(&xw, &gui.input, &evt, zr_false); else if (evt.type == ButtonPress) btn(&gui.input, &evt, zr_true); else if (evt.type == ButtonRelease) btn(&gui.input, &evt, zr_false); else if (evt.type == MotionNotify) motion(&gui.input, &evt); else if (evt.type == Expose || evt.type == ConfigureNotify) resize(&xw, xw.surf); } zr_input_end(&gui.input); /* GUI */ run_demo(&gui); /* Draw */ XClearWindow(xw.dpy, xw.win); surface_clear(xw.surf, 0x00646464); draw(xw.surf, &gui.queue); surface_blit(xw.win, xw.surf, xw.width, xw.height); XFlush(xw.dpy); /* Timing */ dt = timestamp() - started; if (dt < DTIME) sleep_for(DTIME - dt); } free(zr_buffer_memory(&gui.queue.buffer)); font_del(xw.dpy, xw.font); surface_del(xw.surf); XUnmapWindow(xw.dpy, xw.win); XFreeColormap(xw.dpy, xw.cmap); XDestroyWindow(xw.dpy, xw.win); XCloseDisplay(xw.dpy); return 0; }