static int cr_set_scaled_font (lua_State *L) { cairo_t **obj = luaL_checkudata(L, 1, OOCAIRO_MT_NAME_CONTEXT); cairo_scaled_font_t **font = luaL_checkudata(L, 2, OOCAIRO_MT_NAME_SCALEDFONT); cairo_set_scaled_font(*obj, *font); return 0; }
static VALUE cr_set_scaled_font (VALUE self, VALUE scaled_font) { cairo_set_scaled_font (_SELF, RVAL2CRSCALEDFONT (scaled_font)); cr_check_status (_SELF); return self; }
void SystemDraw::DrawTextOp(int x, int y, int angle, const wchar *text, Font font, Color ink, int n, const int *dx) { GuiLock __; int ascent = font.GetAscent(); double sina = 0; double cosa = 1; if(angle) Draw::SinCos(angle, sina, cosa); int xpos = 0; Buffer<cairo_glyph_t> gs(n); for(int i = 0; i < n; i++) { cairo_glyph_t& g = gs[i]; g.index = GetGlyphInfo(font, text[i]).glyphi; g.x = fround(x + cosa * xpos + sina * ascent); g.y = fround(y + cosa * ascent - sina * xpos); xpos += dx ? dx[i] : font[text[i]]; } static LRUCache<FontSysData, Tuple2<Font, int> > cache; FontDataSysMaker m; m.font = font; m.angle = angle; FontSysData& sf = cache.Get(m); cairo_set_scaled_font(cr, sf.scaled_font); SetColor(ink); cairo_show_glyphs(cr, gs, n); cache.Shrink(64); }
static cairo_test_status_t draw (cairo_t *cr, int width, int height) { cairo_font_face_t *font_face; cairo_font_options_t *font_options; cairo_scaled_font_t *scaled_font; cairo_matrix_t identity; cairo_matrix_t zero; cairo_matrix_init_identity(&identity); zero = identity; cairo_matrix_scale(&zero, 0, 0); font_face = cairo_get_font_face (cr); font_options = cairo_font_options_create (); cairo_get_font_options (cr, font_options); scaled_font = cairo_scaled_font_create (font_face, &identity, &zero, font_options); cairo_set_scaled_font (cr, scaled_font); cairo_show_text (cr, "Hello"); cairo_scaled_font_destroy (scaled_font); cairo_font_options_destroy (font_options); return cairo_test_status_from_status (cairo_test_get_context (cr), cairo_status(cr)); }
void ScaledFontBase::CopyGlyphsToBuilder(const GlyphBuffer &aBuffer, PathBuilder *aBuilder, const Matrix *aTransformHint) { #ifdef USE_CAIRO PathBuilderCairo* builder = static_cast<PathBuilderCairo*>(aBuilder); cairo_t *ctx = cairo_create(DrawTargetCairo::GetDummySurface()); if (aTransformHint) { cairo_matrix_t mat; GfxMatrixToCairoMatrix(*aTransformHint, mat); cairo_set_matrix(ctx, &mat); } // Convert our GlyphBuffer into an array of Cairo glyphs. std::vector<cairo_glyph_t> glyphs(aBuffer.mNumGlyphs); for (uint32_t i = 0; i < aBuffer.mNumGlyphs; ++i) { glyphs[i].index = aBuffer.mGlyphs[i].mIndex; glyphs[i].x = aBuffer.mGlyphs[i].mPosition.x; glyphs[i].y = aBuffer.mGlyphs[i].mPosition.y; } cairo_set_scaled_font(ctx, mScaledFont); cairo_glyph_path(ctx, &glyphs[0], aBuffer.mNumGlyphs); RefPtr<PathCairo> cairoPath = new PathCairo(ctx); cairo_destroy(ctx); cairoPath->AppendPathToBuilder(builder); #endif }
static void text_layout_draw(struct text_layout *layout, cairo_t *cr) { cairo_save(cr); cairo_set_scaled_font(cr, layout->font); cairo_show_glyphs(cr, layout->glyphs, layout->num_glyphs); cairo_restore(cr); }
static void prepareContextForGlyphDrawing(cairo_t* context, const SimpleFontData* font) { cairo_set_scaled_font(context, font->platformData().scaledFont()); if (font->platformData().syntheticOblique()) { cairo_matrix_t mat = {1, 0, gSyntheticObliqueSkew, 1, 0, 0}; cairo_transform(context, &mat); } }
static cairo_test_status_t draw (cairo_t *cr, int width, int height) { cairo_text_extents_t extents; cairo_scaled_font_t *scaled_font; cairo_status_t status; const char text[] = "i-W"; double line_width, x, y; line_width = cairo_get_line_width (cr); /* We draw in the default black, so paint white first. */ cairo_save (cr); cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */ cairo_paint (cr); cairo_restore (cr); status = create_scaled_font (cr, &scaled_font); if (status) { return cairo_test_status_from_status (cairo_test_get_context (cr), status); } cairo_set_scaled_font (cr, scaled_font); cairo_scaled_font_destroy (scaled_font); cairo_set_line_width (cr, 1.0); cairo_set_source_rgb (cr, 0, 0, 0); /* black */ cairo_text_extents (cr, text, &extents); x = width - (extents.width + extents.x_bearing) - 5; y = height - (extents.height + extents.y_bearing) - 5; cairo_move_to (cr, x, y); cairo_show_text (cr, text); cairo_rectangle (cr, x + extents.x_bearing - line_width / 2, y + extents.y_bearing - line_width / 2, extents.width + line_width, extents.height + line_width); cairo_stroke (cr); cairo_set_source_rgb (cr, 0, 0, 1); /* blue */ cairo_text_extents (cr, text, &extents); x = -extents.x_bearing + 5; y = -extents.y_bearing + 5; cairo_move_to (cr, x, y); cairo_text_path (cr, text); cairo_fill (cr); cairo_rectangle (cr, x + extents.x_bearing - line_width / 2, y + extents.y_bearing - line_width / 2, extents.width + line_width, extents.height + line_width); cairo_stroke (cr); return CAIRO_TEST_SUCCESS; }
bool GlyphLayerBevel::render( cairo_t* c, cairo_glyph_t* glyph, unsigned int width, unsigned int height ) { if(cairo_status(c) || !glyph) return false; cairo_surface_t* bumpmap = cairo_image_surface_create(CAIRO_FORMAT_A8, width, height); cairo_t* cr = cairo_create(bumpmap); cairo_set_scaled_font(cr, cairo_get_scaled_font(c)); cairo_glyph_path(cr, glyph, 1); cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); for(double l = _bevelWidth; l > 0.0f; l -= _bevelStep) { cairo_set_source_rgba(cr, 1.0f, 1.0f, 1.0f, 1.0f - (l / _bevelWidth)); cairo_set_line_width(cr, l); cairo_stroke_preserve(cr); } cairo_destroy(cr); cairo_surface_t* lightmap = osgPairo::createEmbossedSurface( bumpmap, _azimuth, _elevation, _height, _ambient, _diffuse ); cairo_glyph_path(c, glyph, 1); cairo_save(c); cairo_clip_preserve(c); cairo_set_operator(c, CAIRO_OPERATOR_SOURCE); cairo_set_source_surface(c, lightmap, 0, 0); cairo_paint(c); cairo_set_operator(c, CAIRO_OPERATOR_SATURATE); cairo_set_source_rgba(c, 1.0f, 1.0f, 1.0f, 1.0f); cairo_paint(c); cairo_restore(c); // TODO: This is a hack! Figure out why the border is poor quality... cairo_set_line_width(c, 4.0); cairo_set_operator(c, CAIRO_OPERATOR_CLEAR); cairo_stroke(c); // cairo_surface_write_to_png(bumpmap, "bumpmap.png"); // cairo_surface_write_to_png(lightmap, "lightmap.png"); cairo_surface_destroy(bumpmap); cairo_surface_destroy(lightmap); return true; }
static PyObject * pycairo_set_scaled_font(PycairoContext *o, PyObject *args) { PycairoScaledFont *f; if (!PyArg_ParseTuple( args, "O!:Context.set_scaled_font", &PycairoScaledFont_Type, &f)) return NULL; cairo_set_scaled_font(o->ctx, f->scaled_font); RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); Py_RETURN_NONE; }
TemporaryRef<Path> ScaledFontBase::GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget *aTarget) { #ifdef USE_SKIA if (aTarget->GetType() == BACKEND_SKIA) { SkPaint paint; paint.setTypeface(GetSkTypeface()); paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); paint.setTextSize(SkFloatToScalar(mSize)); std::vector<uint16_t> indices; std::vector<SkPoint> offsets; indices.resize(aBuffer.mNumGlyphs); offsets.resize(aBuffer.mNumGlyphs); for (unsigned int i = 0; i < aBuffer.mNumGlyphs; i++) { indices[i] = aBuffer.mGlyphs[i].mIndex; offsets[i].fX = SkFloatToScalar(aBuffer.mGlyphs[i].mPosition.x); offsets[i].fY = SkFloatToScalar(aBuffer.mGlyphs[i].mPosition.y); } SkPath path; paint.getPosTextPath(&indices.front(), aBuffer.mNumGlyphs*2, &offsets.front(), &path); return new PathSkia(path, FILL_WINDING); } #endif #ifdef USE_CAIRO if (aTarget->GetType() == BACKEND_CAIRO) { MOZ_ASSERT(mScaledFont); RefPtr<PathBuilder> builder_iface = aTarget->CreatePathBuilder(); PathBuilderCairo* builder = static_cast<PathBuilderCairo*>(builder_iface.get()); // Manually build the path for the PathBuilder. RefPtr<CairoPathContext> context = builder->GetPathContext(); cairo_set_scaled_font(*context, mScaledFont); // Convert our GlyphBuffer into an array of Cairo glyphs. std::vector<cairo_glyph_t> glyphs(aBuffer.mNumGlyphs); for (uint32_t i = 0; i < aBuffer.mNumGlyphs; ++i) { glyphs[i].index = aBuffer.mGlyphs[i].mIndex; glyphs[i].x = aBuffer.mGlyphs[i].mPosition.x; glyphs[i].y = aBuffer.mGlyphs[i].mPosition.y; } cairo_glyph_path(*context, &glyphs[0], aBuffer.mNumGlyphs); return builder->Finish(); } #endif return NULL; }
PRBool gfxDWriteFont::SetupCairoFont(gfxContext *aContext) { cairo_scaled_font_t *scaledFont = CairoScaledFont(); if (cairo_scaled_font_status(scaledFont) != CAIRO_STATUS_SUCCESS) { // Don't cairo_set_scaled_font as that would propagate the error to // the cairo_t, precluding any further drawing. return PR_FALSE; } cairo_set_scaled_font(aContext->GetCairo(), scaledFont); return PR_TRUE; }
/** * _pango_cairo_font_install: * @font: a #PangoCairoFont * @cr: a #cairo_t * * Makes @font the current font for rendering in the specified * Cairo context. * * Return value: %TRUE if font was installed successfully, %FALSE otherwise. **/ gboolean _pango_cairo_font_install (PangoFont *font, cairo_t *cr) { cairo_scaled_font_t *scaled_font = pango_cairo_font_get_scaled_font ((PangoCairoFont *)font); if (G_UNLIKELY (scaled_font == NULL || cairo_scaled_font_status (scaled_font) != CAIRO_STATUS_SUCCESS)) return FALSE; cairo_set_scaled_font (cr, scaled_font); return TRUE; }
void ScaledFontBase::CopyGlyphsToBuilder(const GlyphBuffer &aBuffer, PathBuilder *aBuilder, const Matrix *aTransformHint) { BackendType backendType = aBuilder->GetBackendType(); #ifdef USE_SKIA if (backendType == BackendType::SKIA) { PathBuilderSkia *builder = static_cast<PathBuilderSkia*>(aBuilder); builder->AppendPath(GetSkiaPathForGlyphs(aBuffer)); return; } #endif #ifdef USE_CAIRO if (backendType == BackendType::CAIRO) { MOZ_ASSERT(mScaledFont); PathBuilderCairo* builder = static_cast<PathBuilderCairo*>(aBuilder); cairo_t *ctx = cairo_create(DrawTargetCairo::GetDummySurface()); if (aTransformHint) { cairo_matrix_t mat; GfxMatrixToCairoMatrix(*aTransformHint, mat); cairo_set_matrix(ctx, &mat); } // Convert our GlyphBuffer into an array of Cairo glyphs. std::vector<cairo_glyph_t> glyphs(aBuffer.mNumGlyphs); for (uint32_t i = 0; i < aBuffer.mNumGlyphs; ++i) { glyphs[i].index = aBuffer.mGlyphs[i].mIndex; glyphs[i].x = aBuffer.mGlyphs[i].mPosition.x; glyphs[i].y = aBuffer.mGlyphs[i].mPosition.y; } cairo_set_scaled_font(ctx, mScaledFont); cairo_glyph_path(ctx, &glyphs[0], aBuffer.mNumGlyphs); RefPtr<PathCairo> cairoPath = new PathCairo(ctx); cairo_destroy(ctx); cairoPath->AppendPathToBuilder(builder); return; } if (backendType == BackendType::RECORDING) { SkPath skPath = GetSkiaPathForGlyphs(aBuffer); RefPtr<Path> path = MakeAndAddRef<PathSkia>(skPath, FillRule::FILL_WINDING); path->StreamToSink(aBuilder); return; } MOZ_ASSERT(false, "Path not being copied"); #endif }
void CairoFont::drawString(gcn::Graphics* graphics, const std::string& text, int x, int y) { CairoGraphics* gr=dynamic_cast<CairoGraphics*>(graphics); if (gr==NULL) { GCN_EXCEPTION("The graphics object passed as parameter is not of type CairoGraphics"); } cairo_t* target=gr->GetContext(); ClipRectangle r=gr->getCurrentClipArea(); cairo_set_scaled_font(target,mFontFace); cairo_move_to(target,r.xOffset+x,mFontExtents.ascent+r.yOffset+y); cairo_set_source_rgba(target,mColorR,mColorG,mColorB,mColorA); cairo_show_text(target,text.c_str()); }
bool gfxGDIFont::SetupCairoFont(gfxContext *aContext) { if (!mMetrics) { Initialize(); } if (!mScaledFont || cairo_scaled_font_status(mScaledFont) != CAIRO_STATUS_SUCCESS) { // Don't cairo_set_scaled_font as that would propagate the error to // the cairo_t, precluding any further drawing. return false; } cairo_set_scaled_font(aContext->GetCairo(), mScaledFont); return true; }
already_AddRefed<Path> ScaledFontBase::GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget *aTarget) { #ifdef USE_SKIA if (aTarget->GetBackendType() == BackendType::SKIA) { SkPath path = GetSkiaPathForGlyphs(aBuffer); return MakeAndAddRef<PathSkia>(path, FillRule::FILL_WINDING); } #endif #ifdef USE_CAIRO if (aTarget->GetBackendType() == BackendType::CAIRO) { MOZ_ASSERT(mScaledFont); DrawTarget *dt = const_cast<DrawTarget*>(aTarget); cairo_t *ctx = static_cast<cairo_t*>(dt->GetNativeSurface(NativeSurfaceType::CAIRO_CONTEXT)); bool isNewContext = !ctx; if (!ctx) { ctx = cairo_create(DrawTargetCairo::GetDummySurface()); cairo_matrix_t mat; GfxMatrixToCairoMatrix(aTarget->GetTransform(), mat); cairo_set_matrix(ctx, &mat); } cairo_set_scaled_font(ctx, mScaledFont); // Convert our GlyphBuffer into an array of Cairo glyphs. std::vector<cairo_glyph_t> glyphs(aBuffer.mNumGlyphs); for (uint32_t i = 0; i < aBuffer.mNumGlyphs; ++i) { glyphs[i].index = aBuffer.mGlyphs[i].mIndex; glyphs[i].x = aBuffer.mGlyphs[i].mPosition.x; glyphs[i].y = aBuffer.mGlyphs[i].mPosition.y; } cairo_new_path(ctx); cairo_glyph_path(ctx, &glyphs[0], aBuffer.mNumGlyphs); RefPtr<PathCairo> newPath = new PathCairo(ctx); if (isNewContext) { cairo_destroy(ctx); } return newPath.forget(); } #endif return nullptr; }
PRBool gfxGDIFont::SetupCairoFont(gfxContext *aContext) { if (!mMetrics) { Initialize(); } if (!mScaledFont || cairo_scaled_font_status(mScaledFont) != CAIRO_STATUS_SUCCESS) { // Don't cairo_set_scaled_font as that would propagate the error to // the cairo_t, precluding any further drawing. return PR_FALSE; } cairo_set_scaled_font(aContext->GetCairo(), mScaledFont); cairo_win32_scaled_font_select_font(mScaledFont, DCFromContext(aContext)); return PR_TRUE; }
static int m_display_draw_text(lua_State * L) { struct ldisplay_t * display = luaL_checkudata(L, 1, MT_DISPLAY); cairo_scaled_font_t * sfont = luaL_checkudata_scaled_font(L, 2, MT_FONT); const char * text = luaL_optstring(L, 3, NULL); struct lpattern_t * pattern = luaL_checkudata(L, 4, MT_PATTERN); cairo_matrix_t * matrix = luaL_checkudata(L, 5, MT_MATRIX); cairo_t * cr = display->cr[display->index]; cairo_save(cr); cairo_set_scaled_font(cr, sfont); cairo_set_font_matrix(cr, matrix); cairo_text_path(cr, text); cairo_set_source(cr, pattern->pattern); cairo_fill(cr); cairo_restore(cr); return 0; }
static void drawGlyphsToContext(cairo_t* context, const SimpleFontData* font, GlyphBufferGlyph* glyphs, int numGlyphs) { cairo_matrix_t originalTransform; float syntheticBoldOffset = font->syntheticBoldOffset(); if (syntheticBoldOffset) cairo_get_matrix(context, &originalTransform); cairo_set_scaled_font(context, font->platformData().scaledFont()); cairo_show_glyphs(context, glyphs, numGlyphs); if (syntheticBoldOffset) { cairo_translate(context, syntheticBoldOffset, 0); cairo_show_glyphs(context, glyphs, numGlyphs); } if (syntheticBoldOffset) cairo_set_matrix(context, &originalTransform); }
void ScaledFontBase::CopyGlyphsToBuilder(const GlyphBuffer &aBuffer, PathBuilder *aBuilder, BackendType aBackendType, const Matrix *aTransformHint) { #ifdef USE_SKIA if (aBackendType == BackendType::SKIA) { PathBuilderSkia *builder = static_cast<PathBuilderSkia*>(aBuilder); builder->AppendPath(GetSkiaPathForGlyphs(aBuffer)); return; } #endif #ifdef USE_CAIRO if (aBackendType == BackendType::CAIRO) { MOZ_ASSERT(mScaledFont); PathBuilderCairo* builder = static_cast<PathBuilderCairo*>(aBuilder); cairo_t *ctx = cairo_create(DrawTargetCairo::GetDummySurface()); if (aTransformHint) { cairo_matrix_t mat; GfxMatrixToCairoMatrix(*aTransformHint, mat); cairo_set_matrix(ctx, &mat); } // Convert our GlyphBuffer into an array of Cairo glyphs. std::vector<cairo_glyph_t> glyphs(aBuffer.mNumGlyphs); for (uint32_t i = 0; i < aBuffer.mNumGlyphs; ++i) { glyphs[i].index = aBuffer.mGlyphs[i].mIndex; glyphs[i].x = aBuffer.mGlyphs[i].mPosition.x; glyphs[i].y = aBuffer.mGlyphs[i].mPosition.y; } cairo_set_scaled_font(ctx, mScaledFont); cairo_glyph_path(ctx, &glyphs[0], aBuffer.mNumGlyphs); RefPtr<PathCairo> cairoPath = new PathCairo(ctx); cairo_destroy(ctx); cairoPath->AppendPathToBuilder(builder); return; } #endif MOZ_CRASH("The specified backend type is not supported by CopyGlyphsToBuilder"); }
Path CairoGlyphToPathTranslator::path() { Path path; path.ensurePlatformPath(); cairo_glyph_t cairoGlyph; cairoGlyph.index = m_glyphBuffer.glyphAt(m_index); cairo_set_scaled_font(path.platformPath()->context(), m_fontData->platformData().scaledFont()); cairo_glyph_path(path.platformPath()->context(), &cairoGlyph, 1); float syntheticBoldOffset = m_fontData->syntheticBoldOffset(); if (syntheticBoldOffset) { cairo_translate(path.platformPath()->context(), syntheticBoldOffset, 0); cairo_show_glyphs(path.platformPath()->context(), &cairoGlyph, 1); } path.transform(m_translation); return path; }
void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point) const { if (!font->platformData().size()) return; GlyphBufferGlyph* glyphs = const_cast<GlyphBufferGlyph*>(glyphBuffer.glyphs(from)); float offset = point.x(); for (int i = 0; i < numGlyphs; i++) { glyphs[i].x = offset; glyphs[i].y = point.y(); offset += glyphBuffer.advanceAt(from + i).width(); } PlatformContextCairo* platformContext = context->platformContext(); drawGlyphsShadow(context, point, font, glyphs, numGlyphs); cairo_t* cr = platformContext->cr(); cairo_save(cr); if (context->textDrawingMode() & TextModeFill) { platformContext->prepareForFilling(context->state(), PlatformContextCairo::AdjustPatternForGlobalAlpha); drawGlyphsToContext(cr, font, glyphs, numGlyphs); } // Prevent running into a long computation within cairo. If the stroke width is // twice the size of the width of the text we will not ask cairo to stroke // the text as even one single stroke would cover the full wdth of the text. // See https://bugs.webkit.org/show_bug.cgi?id=33759. if (context->textDrawingMode() & TextModeStroke && context->strokeThickness() < 2 * offset) { platformContext->prepareForStroking(context->state()); cairo_set_line_width(cr, context->strokeThickness()); // This may disturb the CTM, but we are going to call cairo_restore soon after. cairo_set_scaled_font(cr, font->platformData().scaledFont()); cairo_glyph_path(cr, glyphs, numGlyphs); cairo_stroke(cr); } cairo_restore(cr); }
bool gfxFT2FontBase::SetupCairoFont(gfxContext *aContext) { cairo_t *cr = aContext->GetCairo(); // The scaled font ctm is not relevant right here because // cairo_set_scaled_font does not record the scaled font itself, but // merely the font_face, font_matrix, font_options. The scaled_font used // for the target can be different from the scaled_font passed to // cairo_set_scaled_font. (Unfortunately we have measured only for an // identity ctm.) cairo_scaled_font_t *cairoFont = CairoScaledFont(); if (cairo_scaled_font_status(cairoFont) != CAIRO_STATUS_SUCCESS) { // Don't cairo_set_scaled_font as that would propagate the error to // the cairo_t, precluding any further drawing. return PR_FALSE; } // Thoughts on which font_options to set on the context: // // cairoFont has been created for screen rendering. // // When the context is being used for screen rendering, we should set // font_options such that the same scaled_font gets used (when the ctm is // the same). The use of explicit font_options recorded in // CreateScaledFont ensures that this will happen. // // XXXkt: For pdf and ps surfaces, I don't know whether it's better to // remove surface-specific options, or try to draw with the same // scaled_font that was used to measure. As the same font_face is being // used, its font_options will often override some values anyway (unless // perhaps we remove those from the FcPattern at face creation). // // I can't see any significant difference in printing, irrespective of // what is set here. It's too late to change things here as measuring has // already taken place. We should really be measuring with a different // font for pdf and ps surfaces (bug 403513). cairo_set_scaled_font(cr, cairoFont); return PR_TRUE; }
static void _draw (cairo_t *cr, double red, double green, double blue) { cairo_text_extents_t extents; cairo_set_source_rgb (cr, red, green, blue); cairo_paint (cr); cairo_move_to (cr, 0, 0); cairo_line_to (cr, 1, 1); cairo_stroke (cr); cairo_mask (cr, cairo_get_source (cr)); cairo_set_scaled_font (cr, scaled_font); cairo_text_extents (cr, "cairo", &extents); cairo_move_to (cr, -extents.x_bearing - .5 * extents.width, -extents.y_bearing - .5 * extents.height); cairo_show_text (cr, "cairo"); }
void FontPlatformData::setFont(cairo_t* cr) const { ASSERT(m_scaledFont); cairo_set_scaled_font(cr, m_scaledFont); }
void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point) const { cairo_t* cr = context->platformContext(); cairo_save(cr); cairo_set_scaled_font(cr, font->platformData().scaledFont()); GlyphBufferGlyph* glyphs = (GlyphBufferGlyph*)glyphBuffer.glyphs(from); float offset = 0.0f; for (int i = 0; i < numGlyphs; i++) { glyphs[i].x = offset; glyphs[i].y = 0.0f; offset += glyphBuffer.advanceAt(from + i); } Color fillColor = context->fillColor(); // Synthetic Oblique if(font->platformData().syntheticOblique()) { cairo_matrix_t mat = {1, 0, -tanf(SYNTHETIC_OBLIQUE_ANGLE * acosf(0) / 90), 1, point.x(), point.y()}; cairo_transform(cr, &mat); } else { cairo_translate(cr, point.x(), point.y()); } // Text shadow, inspired by FontMac FloatSize shadowOffset; float shadowBlur = 0; Color shadowColor; bool hasShadow = context->textDrawingMode() & cTextFill && context->getShadow(shadowOffset, shadowBlur, shadowColor); // TODO: Blur support if (hasShadow) { // Disable graphics context shadows (not yet implemented) and paint them manually context->clearShadow(); Color shadowFillColor(shadowColor.red(), shadowColor.green(), shadowColor.blue(), shadowColor.alpha() * fillColor.alpha() / 255); cairo_save(cr); float red, green, blue, alpha; shadowFillColor.getRGBA(red, green, blue, alpha); cairo_set_source_rgba(cr, red, green, blue, alpha); #if ENABLE(FILTERS) cairo_text_extents_t extents; cairo_scaled_font_glyph_extents(font->platformData().scaledFont(), glyphs, numGlyphs, &extents); FloatRect rect(FloatPoint(), FloatSize(extents.width, extents.height)); IntSize shadowBufferSize; FloatRect shadowRect; float radius = 0; context->calculateShadowBufferDimensions(shadowBufferSize, shadowRect, radius, rect, shadowOffset, shadowBlur); // Draw shadow into a new ImageBuffer OwnPtr<ImageBuffer> shadowBuffer = ImageBuffer::create(shadowBufferSize); GraphicsContext* shadowContext = shadowBuffer->context(); cairo_t* shadowCr = shadowContext->platformContext(); cairo_translate(shadowCr, radius, extents.height + radius); cairo_set_scaled_font(shadowCr, font->platformData().scaledFont()); cairo_show_glyphs(shadowCr, glyphs, numGlyphs); if (font->syntheticBoldOffset()) { cairo_save(shadowCr); cairo_translate(shadowCr, font->syntheticBoldOffset(), 0); cairo_show_glyphs(shadowCr, glyphs, numGlyphs); cairo_restore(shadowCr); } cairo_translate(cr, 0.0, -extents.height); context->applyPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, radius); #else cairo_translate(cr, shadowOffset.width(), shadowOffset.height()); cairo_show_glyphs(cr, glyphs, numGlyphs); if (font->syntheticBoldOffset()) { cairo_save(cr); cairo_translate(cr, font->syntheticBoldOffset(), 0); cairo_show_glyphs(cr, glyphs, numGlyphs); cairo_restore(cr); } #endif cairo_restore(cr); } if (context->textDrawingMode() & cTextFill) { if (context->fillGradient()) { cairo_set_source(cr, context->fillGradient()->platformGradient()); if (context->getAlpha() < 1.0f) { cairo_push_group(cr); cairo_paint_with_alpha(cr, context->getAlpha()); cairo_pop_group_to_source(cr); } } else if (context->fillPattern()) { AffineTransform affine; cairo_pattern_t* pattern = context->fillPattern()->createPlatformPattern(affine); cairo_set_source(cr, pattern); if (context->getAlpha() < 1.0f) { cairo_push_group(cr); cairo_paint_with_alpha(cr, context->getAlpha()); cairo_pop_group_to_source(cr); } cairo_pattern_destroy(pattern); } else { float red, green, blue, alpha; fillColor.getRGBA(red, green, blue, alpha); cairo_set_source_rgba(cr, red, green, blue, alpha * context->getAlpha()); } cairo_show_glyphs(cr, glyphs, numGlyphs); if (font->syntheticBoldOffset()) { cairo_save(cr); cairo_translate(cr, font->syntheticBoldOffset(), 0); cairo_show_glyphs(cr, glyphs, numGlyphs); cairo_restore(cr); } } // Prevent running into a long computation within cairo. If the stroke width is // twice the size of the width of the text we will not ask cairo to stroke // the text as even one single stroke would cover the full wdth of the text. // See https://bugs.webkit.org/show_bug.cgi?id=33759. if (context->textDrawingMode() & cTextStroke && context->strokeThickness() < 2 * offset) { if (context->strokeGradient()) { cairo_set_source(cr, context->strokeGradient()->platformGradient()); if (context->getAlpha() < 1.0f) { cairo_push_group(cr); cairo_paint_with_alpha(cr, context->getAlpha()); cairo_pop_group_to_source(cr); } } else if (context->strokePattern()) { AffineTransform affine; cairo_pattern_t* pattern = context->strokePattern()->createPlatformPattern(affine); cairo_set_source(cr, pattern); if (context->getAlpha() < 1.0f) { cairo_push_group(cr); cairo_paint_with_alpha(cr, context->getAlpha()); cairo_pop_group_to_source(cr); } cairo_pattern_destroy(pattern); } else { Color strokeColor = context->strokeColor(); float red, green, blue, alpha; strokeColor.getRGBA(red, green, blue, alpha); cairo_set_source_rgba(cr, red, green, blue, alpha * context->getAlpha()); } cairo_glyph_path(cr, glyphs, numGlyphs); cairo_set_line_width(cr, context->strokeThickness()); cairo_stroke(cr); } // Re-enable the platform shadow we disabled earlier if (hasShadow) context->setShadow(shadowOffset, shadowBlur, shadowColor, DeviceColorSpace); cairo_restore(cr); }
void use() override { cairo_set_scaled_font(m_cairo, m_scaled); }
void Context::setScaledFont( const ScaledFont *scaled_font ) { cairo_set_scaled_font( mCairo, const_cast<ScaledFont *>( scaled_font )->getCairoScaledFont() ); }
TemporaryRef<Path> ScaledFontBase::GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget *aTarget) { #ifdef USE_SKIA if (aTarget->GetType() == BACKEND_SKIA) { SkPaint paint; paint.setTypeface(GetSkTypeface()); paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); paint.setTextSize(SkFloatToScalar(mSize)); std::vector<uint16_t> indices; std::vector<SkPoint> offsets; indices.resize(aBuffer.mNumGlyphs); offsets.resize(aBuffer.mNumGlyphs); for (unsigned int i = 0; i < aBuffer.mNumGlyphs; i++) { indices[i] = aBuffer.mGlyphs[i].mIndex; offsets[i].fX = SkFloatToScalar(aBuffer.mGlyphs[i].mPosition.x); offsets[i].fY = SkFloatToScalar(aBuffer.mGlyphs[i].mPosition.y); } SkPath path; paint.getPosTextPath(&indices.front(), aBuffer.mNumGlyphs*2, &offsets.front(), &path); return new PathSkia(path, FILL_WINDING); } #endif #ifdef USE_CAIRO if (aTarget->GetType() == BACKEND_CAIRO) { MOZ_ASSERT(mScaledFont); DrawTarget *dt = const_cast<DrawTarget*>(aTarget); cairo_t *ctx = static_cast<cairo_t*>(dt->GetNativeSurface(NATIVE_SURFACE_CAIRO_CONTEXT)); bool isNewContext = !ctx; if (!ctx) { ctx = cairo_create(DrawTargetCairo::GetDummySurface()); cairo_matrix_t mat; GfxMatrixToCairoMatrix(aTarget->GetTransform(), mat); cairo_set_matrix(ctx, &mat); } cairo_set_scaled_font(ctx, mScaledFont); // Convert our GlyphBuffer into an array of Cairo glyphs. std::vector<cairo_glyph_t> glyphs(aBuffer.mNumGlyphs); for (uint32_t i = 0; i < aBuffer.mNumGlyphs; ++i) { glyphs[i].index = aBuffer.mGlyphs[i].mIndex; glyphs[i].x = aBuffer.mGlyphs[i].mPosition.x; glyphs[i].y = aBuffer.mGlyphs[i].mPosition.y; } cairo_glyph_path(ctx, &glyphs[0], aBuffer.mNumGlyphs); RefPtr<PathCairo> newPath = new PathCairo(ctx); if (isNewContext) { cairo_destroy(ctx); } return newPath; } #endif return nullptr; }