📄 cairo-directfb-surface.c
字号:
cache->dfb = dfb; cache->width = width; cache->height = height; return cache;}static void_directfb_destroy_font_cache (cairo_directfb_font_cache_t *cache){ cache->buffer->Release (cache->buffer); cache->dfb->Release (cache->dfb); free (cache);}static cairo_status_t_directfb_acquire_font_cache (cairo_directfb_surface_t *surface, cairo_scaled_font_t *scaled_font, const cairo_glyph_t *glyphs, int num_glyphs, cairo_directfb_font_cache_t **ret_cache, DFBRectangle *rects, DFBPoint *points, int *ret_num ){ cairo_status_t ret; cairo_scaled_glyph_t *chars[num_glyphs]; int num_chars = 0; cairo_directfb_font_cache_t *cache = NULL; int n = 0; int x = 0; int y = 0; int w = 8; int h = 8; int i; if (scaled_font->surface_private) { cache = scaled_font->surface_private; x = cache->x; y = cache->y; } for (i = 0; i < num_glyphs; i++) { cairo_scaled_glyph_t *scaled_glyph; cairo_image_surface_t *img; ret = _cairo_scaled_glyph_lookup (scaled_font, glyphs[i].index, CAIRO_SCALED_GLYPH_INFO_SURFACE, &scaled_glyph); if (ret) return ret; img = scaled_glyph->surface; switch (img->format) { case CAIRO_FORMAT_A1: case CAIRO_FORMAT_A8: break; default: D_DEBUG_AT (Cairo_DirectFB, "Unsupported font format %d!\n", img->format); return CAIRO_INT_STATUS_UNSUPPORTED; } points[n].x = floor (glyphs[i].x + img->base.device_transform.x0 + .5); points[n].y = floor (glyphs[i].y + img->base.device_transform.y0 + .5); if (points[n].x >= surface->width || points[n].y >= surface->height || points[n].x+img->width <= 0 || points[n].y+img->height <= 0) continue; if (!scaled_glyph->surface_private) { DFBRectangle *rect; if (x+img->width > 2048) { x = 0; y = h; h = 8; } rects[n].x = x; rects[n].y = y; rects[n].w = img->width; rects[n].h = img->height; x += img->width; h = MAX (h, img->height); w = MAX (w, x); /* Remember glyph location */ rect = malloc (sizeof(DFBRectangle)); if (!rect) return CAIRO_STATUS_NO_MEMORY; *rect = rects[n]; scaled_glyph->surface_private = rect; chars[num_chars++] = scaled_glyph; /*D_DEBUG_AT (Cairo_DirectFB, "Glyph %lu will be loaded at (%d,%d).\n", glyphs[i].index, rects[n].x, rects[n].y);*/ } else { rects[n] = *((DFBRectangle *)scaled_glyph->surface_private); /*D_DEBUG_AT (Cairo_DirectFB, "Glyph %lu already loaded at (%d,%d).\n", glyphs[i].index, rects[n].x, rects[n].y);*/ } n++; } if (!n) return CAIRO_INT_STATUS_NOTHING_TO_DO; h += y; if (cache) { if (cache->width < w || cache->height < h) { cairo_directfb_font_cache_t *new_cache; w = MAX (w, cache->width); h = MAX (h, cache->height); D_DEBUG_AT (Cairo_DirectFB, "Reallocating font cache (%dx%d).\n", w, h); new_cache = _directfb_allocate_font_cache (surface->dfb, w, h); if (!new_cache) return CAIRO_STATUS_NO_MEMORY; new_cache->buffer->Blit (new_cache->buffer, cache->buffer, NULL, 0, 0); _directfb_destroy_font_cache (cache); scaled_font->surface_private = cache = new_cache; } } else { D_DEBUG_AT (Cairo_DirectFB, "Allocating font cache (%dx%d).\n", w, h); cache = _directfb_allocate_font_cache (surface->dfb, w, h); if (!cache) return CAIRO_STATUS_NO_MEMORY; scaled_font->surface_backend = &cairo_directfb_surface_backend; scaled_font->surface_private = cache; } if (num_chars) { unsigned char *data; int pitch; if (cache->buffer->Lock (cache->buffer, DSLF_WRITE, (void *)&data, &pitch)) return CAIRO_STATUS_NO_MEMORY; for (i = 0; i < num_chars; i++) { cairo_image_surface_t *img = chars[i]->surface; DFBRectangle *rect = chars[i]->surface_private; unsigned char *dst = data + rect->y*pitch + rect->x; unsigned char *src = img->data; if (img->format == CAIRO_FORMAT_A1) { int j; for (h = rect->h; h; h--) { for (j = 0; j < rect->w; j++) dst[j] = (src[j>>3] & (1 << (j&7))) ? 0xff : 0x00; dst += pitch; src += img->stride; } } else { for (h = rect->h; h; h--) { direct_memcpy (dst, src, rect->w); dst += pitch; src += img->stride; } } } cache->buffer->Unlock (cache->buffer); } cache->x = x; cache->y = y; *ret_cache = cache; *ret_num = n; return CAIRO_STATUS_SUCCESS;}static void_cairo_directfb_surface_scaled_font_fini (cairo_scaled_font_t *scaled_font){ cairo_directfb_font_cache_t *cache = scaled_font->surface_private; D_DEBUG_AT (Cairo_DirectFB, "%s( scaled_font=%p ).\n", __FUNCTION__, scaled_font); if (cache) { _directfb_destroy_font_cache (cache); scaled_font->surface_private = NULL; }}static void_cairo_directfb_surface_scaled_glyph_fini (cairo_scaled_glyph_t *scaled_glyph, cairo_scaled_font_t *scaled_font){ D_DEBUG_AT (Cairo_DirectFB, "%s( scaled_glyph=%p, scaled_font=%p ).\n", __FUNCTION__, scaled_glyph, scaled_font); if (scaled_glyph->surface_private) { free (scaled_glyph->surface_private); scaled_glyph->surface_private = NULL; }}static cairo_int_status_t_cairo_directfb_surface_show_glyphs ( void *abstract_dst, cairo_operator_t op, cairo_pattern_t *pattern, const cairo_glyph_t *glyphs, int num_glyphs, cairo_scaled_font_t *scaled_font){ cairo_directfb_surface_t *dst = abstract_dst; cairo_directfb_font_cache_t *cache; cairo_status_t ret; DFBSurfaceBlittingFlags flags; DFBSurfaceBlendFunction sblend; DFBSurfaceBlendFunction dblend; DFBColor color; DFBRectangle rects[num_glyphs]; DFBPoint points[num_glyphs]; int num; D_DEBUG_AT (Cairo_DirectFB, "%s( dst=%p, op=%d, pattern=%p, glyphs=%p, num_glyphs=%d, scaled_font=%p ).\n", __FUNCTION__, dst, op, pattern, glyphs, num_glyphs, scaled_font); if (pattern->type != CAIRO_PATTERN_TYPE_SOLID) return CAIRO_INT_STATUS_UNSUPPORTED; if (_directfb_get_operator (op, NULL, &flags, &sblend, &dblend) || sblend == DSBF_DESTALPHA || sblend == DSBF_INVDESTALPHA) return CAIRO_INT_STATUS_UNSUPPORTED; ret = _directfb_acquire_surface (dst, 0); if (ret) return ret; ret = _directfb_acquire_font_cache (dst, scaled_font, glyphs, num_glyphs, &cache, &rects[0], &points[0], &num); if (ret) { if (ret == CAIRO_INT_STATUS_NOTHING_TO_DO) ret = CAIRO_STATUS_SUCCESS; return ret; } color.a = ((cairo_solid_pattern_t *)pattern)->color.alpha_short >> 8; color.r = ((cairo_solid_pattern_t *)pattern)->color.red_short >> 8; color.g = ((cairo_solid_pattern_t *)pattern)->color.green_short >> 8; color.b = ((cairo_solid_pattern_t *)pattern)->color.blue_short >> 8; flags |= DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_COLORIZE; if (color.a != 0xff) flags |= DSBLIT_BLEND_COLORALPHA; if (sblend == DSBF_ONE) { sblend = DSBF_SRCALPHA; if (dblend == DSBF_ZERO) dblend = DSBF_INVSRCALPHA; } dst->buffer->SetBlittingFlags (dst->buffer, flags); dst->buffer->SetSrcBlendFunction (dst->buffer, sblend); dst->buffer->SetDstBlendFunction (dst->buffer, dblend); dst->buffer->SetColor (dst->buffer, color.r, color.g, color.b, color.a); D_DEBUG_AT (Cairo_DirectFB, "Running BatchBlit().\n"); RUN_CLIPPED (dst, NULL, dst->buffer->BatchBlit (dst->buffer, cache->buffer, rects, points, num)); return CAIRO_STATUS_SUCCESS;}#endif /* DFB_SHOW_GLYPHS */static cairo_surface_backend_t cairo_directfb_surface_backend = { CAIRO_SURFACE_TYPE_DIRECTFB, /*type*/ _cairo_directfb_surface_create_similar,/*create_similar*/ _cairo_directfb_surface_finish, /*finish*/ _cairo_directfb_surface_acquire_source_image,/*acquire_source_image*/ _cairo_directfb_surface_release_source_image,/*release_source_image*/ _cairo_directfb_surface_acquire_dest_image,/*acquire_dest_image*/ _cairo_directfb_surface_release_dest_image,/*release_dest_image*/ _cairo_directfb_surface_clone_similar,/*clone_similar*/#if DFB_COMPOSITE _cairo_directfb_surface_composite,/*composite*/#else NULL,/*composite*/#endif _cairo_directfb_surface_fill_rectangles,/*fill_rectangles*/#if DFB_COMPOSITE_TRAPEZOIDS _cairo_directfb_surface_composite_trapezoids,/*composite_trapezoids*/#else NULL,/*composite_trapezoids*/#endif NULL, /* copy_page */ NULL, /* show_page */ _cairo_directfb_surface_set_clip_region,/*set_clip_region*/ NULL, /* intersect_clip_path */ _cairo_directfb_abstract_surface_get_extents,/*get_extents*/ NULL, /* old_show_glyphs */ NULL, /* get_font_options */ _cairo_directfb_surface_flush,/*flush*/ _cairo_directfb_surface_mark_dirty_rectangle,/*mark_dirty_rectangle*/#if DFB_SHOW_GLYPHS _cairo_directfb_surface_scaled_font_fini,/*scaled_font_fini*/ _cairo_directfb_surface_scaled_glyph_fini,/*scaled_glyph_fini*/#else NULL, NULL,#endif NULL, /* paint */ NULL, /* mask */ NULL, /* stroke */ NULL, /* fill */#if DFB_SHOW_GLYPHS _cairo_directfb_surface_show_glyphs,/*show_glyphs*/#else NULL, /* show_glyphs */#endif NULL /* snapshot */};static voidcairo_directfb_surface_backend_init (IDirectFB *dfb){ DFBGraphicsDeviceDescription dsc; static int done = 0; if (done) return; dfb->GetDeviceDescription (dfb, &dsc); #if DFB_COMPOSITE if (!(dsc.acceleration_mask & DFXL_BLIT)) cairo_directfb_surface_backend.composite = NULL;#endif#if DFB_COMPOSITE_TRAPEZOIDS if (!(dsc.acceleration_mask & DFXL_TEXTRIANGLES)) cairo_directfb_surface_backend.composite_trapezoids = NULL;#endif#if DFB_SHOW_GLYPHS if (!(dsc.acceleration_mask & DFXL_BLIT) || !(dsc.blitting_flags & DSBLIT_COLORIZE) || !(dsc.blitting_flags & DSBLIT_BLEND_ALPHACHANNEL)) { cairo_directfb_surface_backend.scaled_font_fini = NULL; cairo_directfb_surface_backend.scaled_glyph_fini = NULL; cairo_directfb_surface_backend.show_glyphs = NULL; }#endif done = 1;} cairo_surface_t *cairo_directfb_surface_create (IDirectFB *dfb, IDirectFBSurface *dfbsurface) { DFBSurfacePixelFormat format; cairo_directfb_surface_t *surface; cairo_directfb_surface_backend_init (dfb); surface = calloc (1, sizeof(cairo_directfb_surface_t)); if (!surface) return NULL; dfbsurface->GetPixelFormat (dfbsurface, &format); _cairo_surface_init (&surface->base, &cairo_directfb_surface_backend, _directfb_format_to_content(format)); dfb->AddRef (dfb); surface->dfb = dfb; dfbsurface->AddRef (dfbsurface); surface->surface = dfbsurface; if (_directfb_acquire_surface (surface, 0)) { cairo_surface_destroy ((cairo_surface_t *)surface); return NULL; } return &surface->base;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -