void ScaledFontBase::GetGlyphDesignMetrics(const uint16_t* aGlyphs, uint32_t aNumGlyphs, GlyphMetrics* aGlyphMetrics) { #ifdef USE_CAIRO_SCALED_FONT if (mScaledFont) { for (uint32_t i = 0; i < aNumGlyphs; i++) { cairo_glyph_t glyph; cairo_text_extents_t extents; glyph.index = aGlyphs[i]; glyph.x = 0; glyph.y = 0; cairo_scaled_font_glyph_extents(mScaledFont, &glyph, 1, &extents); aGlyphMetrics[i].mXBearing = extents.x_bearing; aGlyphMetrics[i].mXAdvance = extents.x_advance; aGlyphMetrics[i].mYBearing = extents.y_bearing; aGlyphMetrics[i].mYAdvance = extents.y_advance; aGlyphMetrics[i].mWidth = extents.width; aGlyphMetrics[i].mHeight = extents.height; cairo_font_options_t *options = cairo_font_options_create(); cairo_scaled_font_get_font_options(mScaledFont, options); if (cairo_font_options_get_antialias(options) != CAIRO_ANTIALIAS_NONE) { if (cairo_scaled_font_get_type(mScaledFont) == CAIRO_FONT_TYPE_WIN32) { if (aGlyphMetrics[i].mWidth > 0 && aGlyphMetrics[i].mHeight > 0) { aGlyphMetrics[i].mWidth -= 3.0f; aGlyphMetrics[i].mXBearing += 1.0f; } } #if defined(MOZ2D_HAS_MOZ_CAIRO) && defined(CAIRO_HAS_DWRITE_FONT) else if (cairo_scaled_font_get_type(mScaledFont) == CAIRO_FONT_TYPE_DWRITE) { if (aGlyphMetrics[i].mWidth > 0 && aGlyphMetrics[i].mHeight > 0) { aGlyphMetrics[i].mWidth -= 2.0f; aGlyphMetrics[i].mXBearing += 1.0f; } } #endif } cairo_font_options_destroy(options); } } #endif // Don't know how to get the glyph metrics... MOZ_CRASH("The specific backend type is not supported for GetGlyphDesignMetrics."); }
static cairo_bool_t check_glyphs (cairo_composite_rectangles_t *composite, cairo_scaled_font_t *scaled_font) { if (! _cairo_clip_is_region (composite->clip)) return FALSE; if (cairo_scaled_font_get_type (scaled_font) != CAIRO_FONT_TYPE_WIN32) return FALSE; if (! _cairo_pattern_is_opaque_solid (&composite->source_pattern.base)) return FALSE; return (composite->op == CAIRO_OPERATOR_CLEAR || composite->op == CAIRO_OPERATOR_SOURCE || composite->op == CAIRO_OPERATOR_OVER); }
int32_t ScaledFont::getType() { return static_cast<int32_t>( cairo_scaled_font_get_type( mCairoScaledFont ) ); }
cairo_int_status_t _cairo_win32_surface_emit_glyphs (cairo_win32_surface_t *dst, const cairo_pattern_t *source, cairo_glyph_t *glyphs, int num_glyphs, cairo_scaled_font_t *scaled_font, cairo_bool_t glyph_indexing) { #if CAIRO_HAS_WIN32_FONT WORD glyph_buf_stack[STACK_GLYPH_SIZE]; WORD *glyph_buf = glyph_buf_stack; int dxy_buf_stack[2 * STACK_GLYPH_SIZE]; int *dxy_buf = dxy_buf_stack; BOOL win_result = 0; int i, j; cairo_solid_pattern_t *solid_pattern; COLORREF color; cairo_matrix_t device_to_logical; int start_x, start_y; double user_x, user_y; int logical_x, logical_y; unsigned int glyph_index_option; /* We can only handle win32 fonts */ assert (cairo_scaled_font_get_type (scaled_font) == CAIRO_FONT_TYPE_WIN32); /* We can only handle opaque solid color sources and destinations */ assert (_cairo_pattern_is_opaque_solid(source)); assert (dst->format == CAIRO_FORMAT_RGB24); solid_pattern = (cairo_solid_pattern_t *)source; color = RGB(((int)solid_pattern->color.red_short) >> 8, ((int)solid_pattern->color.green_short) >> 8, ((int)solid_pattern->color.blue_short) >> 8); cairo_win32_scaled_font_get_device_to_logical(scaled_font, &device_to_logical); SaveDC(dst->dc); cairo_win32_scaled_font_select_font(scaled_font, dst->dc); SetTextColor(dst->dc, color); SetTextAlign(dst->dc, TA_BASELINE | TA_LEFT); SetBkMode(dst->dc, TRANSPARENT); if (num_glyphs > STACK_GLYPH_SIZE) { glyph_buf = (WORD *) _cairo_malloc_ab (num_glyphs, sizeof(WORD)); dxy_buf = (int *) _cairo_malloc_abc (num_glyphs, sizeof(int), 2); } /* It is vital that dx values for dxy_buf are calculated from the delta of * _logical_ x coordinates (not user x coordinates) or else the sum of all * previous dx values may start to diverge from the current glyph's x * coordinate due to accumulated rounding error. As a result strings could * be painted shorter or longer than expected. */ user_x = glyphs[0].x; user_y = glyphs[0].y; cairo_matrix_transform_point(&device_to_logical, &user_x, &user_y); logical_x = _cairo_lround (user_x); logical_y = _cairo_lround (user_y); start_x = logical_x; start_y = logical_y; for (i = 0, j = 0; i < num_glyphs; ++i, j = 2 * i) { glyph_buf[i] = (WORD) glyphs[i].index; if (i == num_glyphs - 1) { dxy_buf[j] = 0; dxy_buf[j+1] = 0; } else { double next_user_x = glyphs[i+1].x; double next_user_y = glyphs[i+1].y; int next_logical_x, next_logical_y; cairo_matrix_transform_point(&device_to_logical, &next_user_x, &next_user_y); next_logical_x = _cairo_lround (next_user_x); next_logical_y = _cairo_lround (next_user_y); dxy_buf[j] = _cairo_lround (next_logical_x - logical_x); dxy_buf[j+1] = _cairo_lround (next_logical_y - logical_y); logical_x = next_logical_x; logical_y = next_logical_y; } } if (glyph_indexing) glyph_index_option = ETO_GLYPH_INDEX; else glyph_index_option = 0; win_result = ExtTextOutW(dst->dc, start_x, start_y, glyph_index_option | ETO_PDY, NULL, glyph_buf, num_glyphs, dxy_buf); if (!win_result) { _cairo_win32_print_gdi_error("_cairo_win32_surface_show_glyphs(ExtTextOutW failed)"); } RestoreDC(dst->dc, -1); if (glyph_buf != glyph_buf_stack) { free(glyph_buf); free(dxy_buf); } return (win_result) ? CAIRO_STATUS_SUCCESS : CAIRO_INT_STATUS_UNSUPPORTED; #else return CAIRO_INT_STATUS_UNSUPPORTED; #endif }