Beispiel #1
0
static void
draw_text (RsvgDrawingCtx * ctx, cairo_t *cr, double *x, double *y,
           const char *text)
{
    PangoContext *context;
    PangoLayout *layout;
    RsvgState *state;
    PangoLayoutLine *line;
    int w, h;

    state = rsvg_current_state (ctx);
    if (state->font_size.length == 0)
        return;

    context = ctx->render->create_pango_context (ctx);
    layout = rsvg_text_create_layout (ctx, state, text, context);
    pango_layout_get_size(layout, &w, &h);

    // From pango example
    // http://git.gnome.org/browse/pango/tree/examples/cairotwisted.c
    line = pango_layout_get_line_readonly (layout, 0);

    cairo_move_to (cr, *x, *y);
    pango_cairo_layout_line_path (cr, line);

    // Update x, y based on dimensions of text drawn
    if (PANGO_GRAVITY_IS_VERTICAL (state->text_gravity))
        *y += w / (double)PANGO_SCALE;
    else
        *x += w / (double)PANGO_SCALE;

    g_object_unref (layout);
    g_object_unref (context);
}
Beispiel #2
0
void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to) const
{
#if defined(USE_FREETYPE)
    if (!primaryFont()->platformData().m_pattern) {
        drawSimpleText(context, run, point, from, to);
        return;
    }
#endif

    cairo_t* cr = context->platformContext();
    PangoLayout* layout = pango_cairo_create_layout(cr);
    setPangoAttributes(this, run, layout);

    gchar* utf8 = convertUniCharToUTF8(run.characters(), run.length(), 0, run.length());
    pango_layout_set_text(layout, utf8, -1);

    // Our layouts are single line
    PangoLayoutLine* layoutLine = pango_layout_get_line_readonly(layout, 0);

    // Get the region where this text will be laid out. We will use it to clip
    // the Cairo context, for when we are only painting part of the text run and
    // to calculate the size of the shadow buffer.
    PangoRegionType partialRegion = 0;
    char* start = g_utf8_offset_to_pointer(utf8, from);
    char* end = g_utf8_offset_to_pointer(start, to - from);
    int ranges[] = {start - utf8, end - utf8};
    partialRegion = gdk_pango_layout_line_get_clip_region(layoutLine, 0, 0, ranges, 1);

    drawGlyphsShadow(context, cr, point, layoutLine, partialRegion);

    cairo_save(cr);
    cairo_translate(cr, point.x(), point.y());

    float red, green, blue, alpha;
    context->fillColor().getRGBA(red, green, blue, alpha);
    cairo_set_source_rgba(cr, red, green, blue, alpha);
    gdk_cairo_region(cr, partialRegion);
    cairo_clip(cr);

    pango_cairo_show_layout_line(cr, layoutLine);

    if (context->textDrawingMode() & TextModeStroke) {
        Color strokeColor = context->strokeColor();
        strokeColor.getRGBA(red, green, blue, alpha);
        cairo_set_source_rgba(cr, red, green, blue, alpha);
        pango_cairo_layout_line_path(cr, layoutLine);
        cairo_set_line_width(cr, context->strokeThickness());
        cairo_stroke(cr);
    }

    // Pango sometimes leaves behind paths we don't want
    cairo_new_path(cr);

    destroyPangoRegion(partialRegion);
    g_free(utf8);
    g_object_unref(layout);

    cairo_restore(cr);
}
Beispiel #3
0
void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to) const
{
    cairo_t* cr = context->platformContext();
    cairo_save(cr);
    cairo_translate(cr, point.x(), point.y());

    PangoLayout* layout = pango_cairo_create_layout(cr);
    setPangoAttributes(this, run, layout);

    gchar* utf8 = convertUniCharToUTF8(run.characters(), run.length(), 0, run.length());
    pango_layout_set_text(layout, utf8, -1);

    // Our layouts are single line
    PangoLayoutLine* layoutLine = pango_layout_get_line_readonly(layout, 0);

    GdkRegion* partialRegion = NULL;
    if (to - from != run.length()) {
        // Clip the region of the run to be rendered
        char* start = g_utf8_offset_to_pointer(utf8, from);
        char* end = g_utf8_offset_to_pointer(start, to - from);
        int ranges[] = {start - utf8, end - utf8};
        partialRegion = gdk_pango_layout_line_get_clip_region(layoutLine, 0, 0, ranges, 1);
        gdk_region_shrink(partialRegion, 0, -pixelSize());
    }

    Color fillColor = context->fillColor();
    float red, green, blue, alpha;

    // Text shadow, inspired by FontMac
    IntSize shadowSize;
    int shadowBlur = 0;
    Color shadowColor;
    bool hasShadow = context->textDrawingMode() == cTextFill &&
        context->getShadow(shadowSize, 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);

        shadowFillColor.getRGBA(red, green, blue, alpha);
        cairo_set_source_rgba(cr, red, green, blue, alpha);

        cairo_translate(cr, shadowSize.width(), shadowSize.height());

        if (partialRegion) {
            gdk_cairo_region(cr, partialRegion);
            cairo_clip(cr);
        }

        pango_cairo_show_layout_line(cr, layoutLine);

        cairo_restore(cr);
    }

    fillColor.getRGBA(red, green, blue, alpha);
    cairo_set_source_rgba(cr, red, green, blue, alpha);

    if (partialRegion) {
        gdk_cairo_region(cr, partialRegion);
        cairo_clip(cr);
    }

    pango_cairo_show_layout_line(cr, layoutLine);

    if (context->textDrawingMode() & cTextStroke) {
        Color strokeColor = context->strokeColor();
        strokeColor.getRGBA(red, green, blue, alpha);
        cairo_set_source_rgba(cr, red, green, blue, alpha);
        pango_cairo_layout_line_path(cr, layoutLine);
        cairo_set_line_width(cr, context->strokeThickness());
        cairo_stroke(cr);
    }

    // Re-enable the platform shadow we disabled earlier
    if (hasShadow)
        context->setShadow(shadowSize, shadowBlur, shadowColor);

    // Pango sometimes leaves behind paths we don't want
    cairo_new_path(cr);

    if (partialRegion)
        gdk_region_destroy(partialRegion);

    g_free(utf8);
    g_object_unref(layout);

    cairo_restore(cr);
}
Beispiel #4
0
static VALUE
rg_pango_layout_line_path(VALUE self, VALUE line)
{
    pango_cairo_layout_line_path(RVAL2CRCONTEXT(self), RVAL2PANGOLAYOUTLINE(line));
    return self;
}