diff --git a/pango/cogl-pango-pipeline-cache.c b/pango/cogl-pango-pipeline-cache.c index ae1397c2a..5f6a5a03a 100644 --- a/pango/cogl-pango-pipeline-cache.c +++ b/pango/cogl-pango-pipeline-cache.c @@ -39,7 +39,8 @@ struct _CoglPangoPipelineCache { GHashTable *hash_table; - CoglPipeline *base_texture_pipeline; + CoglPipeline *base_texture_alpha_pipeline; + CoglPipeline *base_texture_rgba_pipeline; gboolean use_mipmapping; }; @@ -89,7 +90,8 @@ _cogl_pango_pipeline_cache_new (gboolean use_mipmapping) _cogl_pango_pipeline_cache_key_destroy, _cogl_pango_pipeline_cache_value_destroy); - cache->base_texture_pipeline = NULL; + cache->base_texture_rgba_pipeline = NULL; + cache->base_texture_alpha_pipeline = NULL; cache->use_mipmapping = use_mipmapping; @@ -97,13 +99,36 @@ _cogl_pango_pipeline_cache_new (gboolean use_mipmapping) } static CoglPipeline * -get_base_texture_pipeline (CoglPangoPipelineCache *cache) +get_base_texture_rgba_pipeline (CoglPangoPipelineCache *cache) { - if (cache->base_texture_pipeline == NULL) + if (cache->base_texture_rgba_pipeline == NULL) { CoglPipeline *pipeline; - pipeline = cache->base_texture_pipeline = cogl_pipeline_new (); + pipeline = cache->base_texture_rgba_pipeline = cogl_pipeline_new (); + + cogl_pipeline_set_layer_wrap_mode (pipeline, 0, + COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE); + + if (cache->use_mipmapping) + cogl_pipeline_set_layer_filters + (pipeline, 0, + COGL_PIPELINE_FILTER_LINEAR_MIPMAP_LINEAR, + COGL_PIPELINE_FILTER_LINEAR); + } + + return cache->base_texture_rgba_pipeline; +} + +static CoglPipeline * +get_base_texture_alpha_pipeline (CoglPangoPipelineCache *cache) +{ + if (cache->base_texture_alpha_pipeline == NULL) + { + CoglPipeline *pipeline; + + pipeline = cogl_pipeline_copy (get_base_texture_rgba_pipeline (cache)); + cache->base_texture_alpha_pipeline = pipeline; /* The default combine mode of materials is to modulate (A x B) * the texture RGBA channels with the RGBA channels of the @@ -122,17 +147,9 @@ get_base_texture_pipeline (CoglPangoPipelineCache *cache) cogl_pipeline_set_layer_combine (pipeline, 0, /* layer */ "RGBA = MODULATE (PREVIOUS, TEXTURE[A])", NULL); - cogl_pipeline_set_layer_wrap_mode (pipeline, 0, - COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE); - - if (cache->use_mipmapping) - cogl_pipeline_set_layer_filters - (pipeline, 0, - COGL_PIPELINE_FILTER_LINEAR_MIPMAP_LINEAR, - COGL_PIPELINE_FILTER_LINEAR); } - return cache->base_texture_pipeline; + return cache->base_texture_alpha_pipeline; } typedef struct @@ -169,8 +186,16 @@ _cogl_pango_pipeline_cache_get (CoglPangoPipelineCache *cache, if (texture) { + CoglPipeline *base; + entry->texture = cogl_handle_ref (texture); - entry->pipeline = cogl_pipeline_copy (get_base_texture_pipeline (cache)); + + if (cogl_texture_get_format (entry->texture) == COGL_PIXEL_FORMAT_A_8) + base = get_base_texture_alpha_pipeline (cache); + else + base = get_base_texture_rgba_pipeline (cache); + + entry->pipeline = cogl_pipeline_copy (base); cogl_pipeline_set_layer_texture (entry->pipeline, 0 /* layer */, texture); } @@ -202,8 +227,10 @@ _cogl_pango_pipeline_cache_get (CoglPangoPipelineCache *cache, void _cogl_pango_pipeline_cache_free (CoglPangoPipelineCache *cache) { - if (cache->base_texture_pipeline) - cogl_object_unref (cache->base_texture_pipeline); + if (cache->base_texture_rgba_pipeline) + cogl_object_unref (cache->base_texture_rgba_pipeline); + if (cache->base_texture_alpha_pipeline) + cogl_object_unref (cache->base_texture_alpha_pipeline); g_hash_table_destroy (cache->hash_table); diff --git a/pango/cogl-pango-render.c b/pango/cogl-pango-render.c index 7fa7c5784..72cfbcb15 100644 --- a/pango/cogl-pango-render.c +++ b/pango/cogl-pango-render.c @@ -467,6 +467,8 @@ cogl_pango_renderer_set_dirty_glyph (PangoFont *font, cairo_t *cr; cairo_scaled_font_t *scaled_font; cairo_glyph_t cairo_glyph; + cairo_format_t format_cairo; + CoglPixelFormat format_cogl; COGL_NOTE (PANGO, "redrawing glyph %i", glyph); @@ -475,7 +477,27 @@ cogl_pango_renderer_set_dirty_glyph (PangoFont *font, here */ g_return_if_fail (value->texture != COGL_INVALID_HANDLE); - surface = cairo_image_surface_create (CAIRO_FORMAT_A8, + if (cogl_texture_get_format (value->texture) == COGL_PIXEL_FORMAT_A_8) + { + format_cairo = CAIRO_FORMAT_A8; + format_cogl = COGL_PIXEL_FORMAT_A_8; + } + else + { + format_cairo = CAIRO_FORMAT_ARGB32; + + /* Cairo stores the data in native byte order as ARGB but Cogl's + pixel formats specify the actual byte order. Therefore we + need to use a different format depending on the + architecture */ +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + format_cogl = COGL_PIXEL_FORMAT_BGRA_8888_PRE; +#else + format_cogl = COGL_PIXEL_FORMAT_ARGB_8888_PRE; +#endif + } + + surface = cairo_image_surface_create (format_cairo, value->draw_width, value->draw_height); cr = cairo_create (surface); @@ -483,6 +505,8 @@ cogl_pango_renderer_set_dirty_glyph (PangoFont *font, scaled_font = pango_cairo_font_get_scaled_font (PANGO_CAIRO_FONT (font)); cairo_set_scaled_font (cr, scaled_font); + cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 1.0); + cairo_glyph.x = -value->draw_x; cairo_glyph.y = -value->draw_y; /* The PangoCairo glyph numbers directly map to Cairo glyph @@ -503,7 +527,7 @@ cogl_pango_renderer_set_dirty_glyph (PangoFont *font, value->draw_height, /* dst_height */ value->draw_width, /* width */ value->draw_height, /* height */ - COGL_PIXEL_FORMAT_A_8, + format_cogl, cairo_image_surface_get_stride (surface), cairo_image_surface_get_data (surface));