Exemplo n.º 1
0
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
    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);

        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 kernelSize = 0.f;
        GraphicsContext::calculateShadowBufferDimensions(shadowBufferSize, shadowRect, kernelSize, rect, shadowSize, 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, kernelSize, extents.height + kernelSize);

        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->createPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, kernelSize);
#else
        cairo_translate(cr, shadowSize.width(), shadowSize.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()) {
            TransformationMatrix affine;
            cairo_set_source(cr, context->fillPattern()->createPlatformPattern(affine));
            if (context->getAlpha() < 1.0f) {
                cairo_push_group(cr);
                cairo_paint_with_alpha(cr, context->getAlpha());
                cairo_pop_group_to_source(cr);
            }
        } 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);
        }
    }

    if (context->textDrawingMode() & cTextStroke) {
        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()) {
            TransformationMatrix affine;
            cairo_set_source(cr, context->strokePattern()->createPlatformPattern(affine));
            if (context->getAlpha() < 1.0f) {
                cairo_push_group(cr);
                cairo_paint_with_alpha(cr, context->getAlpha());
                cairo_pop_group_to_source(cr);
            }
        } 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(shadowSize, shadowBlur, shadowColor, DeviceColorSpace);

    cairo_restore(cr);
}
Exemplo n.º 2
0
/**
 * ags_note_edit_reset_horizontally:
 * @note_edit: the #AgsNoteEdit
 * @flags: the #AgsNoteEditResetFlags
 *
 * Reset @note_edit as configured horizontally.
 *
 * Since: 0.4
 */
void
ags_note_edit_reset_horizontally(AgsNoteEdit *note_edit, guint flags)
{
  AgsEditor *editor;
  double tact_factor, zoom_factor;
  double tact;

  editor = (AgsEditor *) gtk_widget_get_ancestor(GTK_WIDGET(note_edit),
						 AGS_TYPE_EDITOR);

  zoom_factor = 1.0 / 4.0;

  tact_factor = exp2(8.0 - (double) gtk_combo_box_get_active(editor->toolbar->zoom));
  tact = exp2((double) gtk_combo_box_get_active(editor->toolbar->zoom) - 4.0);

  if((AGS_NOTE_EDIT_RESET_WIDTH & flags) != 0){
    note_edit->control_unit.control_width = (guint) (((double) note_edit->control_width * zoom_factor * tact));

    note_edit->control_current.control_count = (guint) ((double) note_edit->control_unit.control_count * tact);
    note_edit->control_current.control_width = (note_edit->control_width * zoom_factor * tact_factor * tact);

    note_edit->map_width = (guint) ((double) note_edit->control_current.control_count * (double) note_edit->control_current.control_width);
    /* reset ruler */
    note_edit->ruler->factor = tact_factor;
    note_edit->ruler->precision = tact;
    note_edit->ruler->scale_precision = 1.0 / tact;

    gtk_widget_queue_draw(note_edit->ruler);
  }

  if(editor->selected_machine != NULL){
    cairo_t *cr;
    gdouble value;

    value = GTK_RANGE(note_edit->hscrollbar)->adjustment->value;

    if((AGS_NOTE_EDIT_RESET_HSCROLLBAR & flags) != 0){
      GtkWidget *widget;
      GtkAdjustment *adjustment;
      guint width;

      widget = GTK_WIDGET(note_edit->drawing_area);
      adjustment = GTK_RANGE(note_edit->hscrollbar)->adjustment;

      if(note_edit->map_width > widget->allocation.width){
	width = widget->allocation.width;
	//	gtk_adjustment_set_upper(adjustment, (double) (note_edit->map_width - width));
	gtk_adjustment_set_upper(adjustment,
				 (gdouble) (note_edit->map_width - width));
	gtk_adjustment_set_upper(note_edit->ruler->adjustment,
				 (gdouble) (note_edit->map_width - width) / note_edit->control_current.control_width);

	if(adjustment->value > adjustment->upper){
	  gtk_adjustment_set_value(adjustment, adjustment->upper);

	  /* reset ruler */
	  gtk_adjustment_set_value(note_edit->ruler->adjustment, note_edit->ruler->adjustment->upper);
	  gtk_widget_queue_draw(note_edit->ruler);
	}
      }else{
	width = note_edit->map_width;

	gtk_adjustment_set_upper(adjustment, 0.0);
	gtk_adjustment_set_value(adjustment, 0.0);
	
	/* reset ruler */
	gtk_adjustment_set_upper(note_edit->ruler->adjustment, 0.0);
	gtk_adjustment_set_value(note_edit->ruler->adjustment, 0.0);
	gtk_widget_queue_draw(note_edit->ruler);
      }

      note_edit->width = width;
    }

    /* reset AgsNoteEditControlCurrent */
    if(note_edit->map_width > note_edit->width){
      note_edit->control_current.x0 = ((guint) round((double) value)) % note_edit->control_current.control_width;

      if(note_edit->control_current.x0 != 0){
	note_edit->control_current.x0 = note_edit->control_current.control_width - note_edit->control_current.x0;
      }

      note_edit->control_current.x1 = (note_edit->width - note_edit->control_current.x0) % note_edit->control_current.control_width;

      note_edit->control_current.nth_x = (guint) ceil((double)(value) / (double)(note_edit->control_current.control_width));
    }else{
      note_edit->control_current.x0 = 0;
      note_edit->control_current.x1 = 0;
      note_edit->control_current.nth_x = 0;
    }

    /* reset AgsNoteEditControlUnit */
    if(note_edit->map_width > note_edit->width){
      note_edit->control_unit.x0 = ((guint)round((double) value)) % note_edit->control_unit.control_width;

      if(note_edit->control_unit.x0 != 0)
	note_edit->control_unit.x0 = note_edit->control_unit.control_width - note_edit->control_unit.x0;
      
      note_edit->control_unit.x1 = (note_edit->width - note_edit->control_unit.x0) % note_edit->control_unit.control_width;
      
      note_edit->control_unit.nth_x = (guint) ceil(round((double) value) / (double) (note_edit->control_unit.control_width));
      note_edit->control_unit.stop_x = note_edit->control_unit.nth_x + (note_edit->width - note_edit->control_unit.x0 - note_edit->control_unit.x1) / note_edit->control_unit.control_width;
    }else{
      note_edit->control_unit.x0 = 0;
      note_edit->control_unit.x1 = 0;
      note_edit->control_unit.nth_x = 0;
    }

    /* refresh display */
    if(GTK_WIDGET_VISIBLE(editor)){
      gdouble position;
      
      cr = gdk_cairo_create(GTK_WIDGET(note_edit->drawing_area)->window);
      cairo_push_group(cr);

      ags_note_edit_draw_segment(note_edit, cr);
      ags_note_edit_draw_notation(note_edit, cr);

      if(editor->toolbar->selected_edit_mode == editor->toolbar->position){
	ags_note_edit_draw_position(note_edit, cr);
      }

      //TODO:JK: implement me
      //      position = gtk_range_get_value(GTK_RANGE(note_edit->hscrollbar));
      //      position -= floor(position / note_edit->control_current.control_width);
      //      ags_note_edit_draw_scroll(note_edit, cr,
      //				position);

      cairo_pop_group_to_source(cr);
      cairo_paint(cr);
    }
  }
}
Exemplo n.º 3
0
static cairo_surface_t* fading_label_make_surface (FadingLabel* self, cairo_t* orig_c) {
	cairo_surface_t* result = NULL;
	gint w = 0;
	gint h = 0;
	PangoLayout* _tmp0_ = NULL;
	gint _tmp1_ = 0;
	gint _tmp2_ = 0;
	gint _tmp3_ = 0;
	gint bw;
	gint _tmp4_ = 0;
	gint bh;
	cairo_t* _tmp5_;
	cairo_surface_t* _tmp6_ = NULL;
	gint _tmp7_;
	gint _tmp8_;
	cairo_surface_t* _tmp9_;
	cairo_surface_t* surface;
	cairo_surface_t* _tmp10_;
	cairo_t* _tmp11_;
	cairo_t* c;
	gint _tmp12_;
	gint _tmp13_;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (orig_c != NULL, NULL);
	_tmp0_ = gtk_label_get_layout ((GtkLabel*) self);
	pango_layout_get_pixel_size (_tmp0_, &_tmp1_, &_tmp2_);
	w = _tmp1_;
	h = _tmp2_;
	_tmp3_ = gtk_widget_get_allocated_width ((GtkWidget*) self);
	bw = _tmp3_;
	_tmp4_ = gtk_widget_get_allocated_height ((GtkWidget*) self);
	bh = _tmp4_;
	_tmp5_ = orig_c;
	_tmp6_ = cairo_get_target (_tmp5_);
	_tmp7_ = bw;
	_tmp8_ = bh;
	_tmp9_ = cairo_surface_create_similar (_tmp6_, CAIRO_CONTENT_COLOR_ALPHA, _tmp7_, _tmp8_);
	surface = _tmp9_;
	_tmp10_ = surface;
	_tmp11_ = cairo_create (_tmp10_);
	c = _tmp11_;
	_tmp12_ = w;
	_tmp13_ = bw;
	if (_tmp12_ > _tmp13_) {
		cairo_t* _tmp14_;
		cairo_t* _tmp15_;
		cairo_t* _tmp16_;
		gint _tmp17_;
		cairo_pattern_t* _tmp18_;
		cairo_pattern_t* mask;
		cairo_pattern_t* _tmp19_;
		gint _tmp20_;
		cairo_pattern_t* _tmp21_;
		gint _tmp22_;
		cairo_pattern_t* _tmp23_;
		cairo_t* _tmp24_;
		cairo_pattern_t* _tmp25_;
		_tmp14_ = c;
		cairo_push_group (_tmp14_);
		_tmp15_ = c;
		GTK_WIDGET_CLASS (fading_label_parent_class)->draw ((GtkWidget*) G_TYPE_CHECK_INSTANCE_CAST (self, GTK_TYPE_LABEL, GtkLabel), _tmp15_);
		_tmp16_ = c;
		cairo_pop_group_to_source (_tmp16_);
		_tmp17_ = bw;
		_tmp18_ = cairo_pattern_create_linear ((gdouble) 0, (gdouble) 0, (gdouble) _tmp17_, (gdouble) 0);
		mask = _tmp18_;
		_tmp19_ = mask;
		_tmp20_ = bw;
		cairo_pattern_add_color_stop_rgba (_tmp19_, 1.0 - (27.0 / _tmp20_), 1.0, 1.0, 1.0, 1.0);
		_tmp21_ = mask;
		_tmp22_ = bw;
		cairo_pattern_add_color_stop_rgba (_tmp21_, 1.0 - (21.6 / _tmp22_), 1.0, 1.0, 1.0, 0.5);
		_tmp23_ = mask;
		cairo_pattern_add_color_stop_rgba (_tmp23_, 1.0, 1.0, 1.0, 1.0, 0.0);
		_tmp24_ = c;
		_tmp25_ = mask;
		cairo_mask (_tmp24_, _tmp25_);
		_cairo_pattern_destroy0 (mask);
	} else {
		cairo_t* _tmp26_;
		_tmp26_ = c;
		GTK_WIDGET_CLASS (fading_label_parent_class)->draw ((GtkWidget*) G_TYPE_CHECK_INSTANCE_CAST (self, GTK_TYPE_LABEL, GtkLabel), _tmp26_);
	}
	result = surface;
	_cairo_destroy0 (c);
	return result;
}
Exemplo n.º 4
0
/**
 * ags_note_edit_reset_vertically:
 * @note_edit: the #AgsNoteEdit
 * @flags: the #AgsNoteEditResetFlags
 *
 * Reset @note_edit as configured vertically.
 *
 * Since: 0.4
 */
void
ags_note_edit_reset_vertically(AgsNoteEdit *note_edit, guint flags)
{
  AgsEditor *editor;

  editor = (AgsEditor *) gtk_widget_get_ancestor(GTK_WIDGET(note_edit),
						 AGS_TYPE_EDITOR);

  if(editor->selected_machine != NULL){
    cairo_t *cr;
    gdouble value;

    value = GTK_RANGE(note_edit->vscrollbar)->adjustment->value;

    if((AGS_NOTE_EDIT_RESET_VSCROLLBAR & flags) != 0){
      GtkWidget *widget;
      GtkAdjustment *adjustment;
      guint height;

      widget = GTK_WIDGET(note_edit->drawing_area);
      adjustment = GTK_RANGE(note_edit->vscrollbar)->adjustment;
      
      if(note_edit->map_height > widget->allocation.height){
	height = widget->allocation.height;
	gtk_adjustment_set_upper(adjustment,
				 (gdouble) (note_edit->map_height - height));
	gtk_adjustment_set_value(adjustment, 0.0);
      }else{
	height = note_edit->map_height;
	
	gtk_adjustment_set_upper(adjustment, 0.0);
	gtk_adjustment_set_value(adjustment, 0.0);
      }
      
      note_edit->height = height;
    }

    note_edit->y0 = ((guint) round((double) value)) % note_edit->control_height;

    if(note_edit->y0 != 0){
      note_edit->y0 = note_edit->control_height - note_edit->y0;
    }

    note_edit->y1 = (note_edit->height - note_edit->y0) % note_edit->control_height;

    note_edit->nth_y = (guint) ceil(round((double) value) / (double)(note_edit->control_height));
    note_edit->stop_y = note_edit->nth_y + (note_edit->height - note_edit->y0 - note_edit->y1) / note_edit->control_height;

    /* refresh display */
    if(GTK_WIDGET_VISIBLE(editor)){
      cr = gdk_cairo_create(GTK_WIDGET(note_edit->drawing_area)->window);
      cairo_push_group(cr);

      ags_note_edit_draw_segment(note_edit, cr);
      ags_note_edit_draw_notation(note_edit, cr);

      if(editor->toolbar->selected_edit_mode == editor->toolbar->position){
	ags_note_edit_draw_position(note_edit, cr);
      }

      cairo_pop_group_to_source(cr);
      cairo_paint(cr);
    }
  }
}
/* TODO: Split each ppi case out to its own CAIRO_TEST() test case */
static cairo_test_status_t
preamble (cairo_test_context_t *ctx)
{
    cairo_t *cr;
    cairo_test_status_t ret = CAIRO_TEST_UNTESTED;
    struct {
	double x, y;
    } ppi[] = {
	{ 576, 576 },
	{ 576, 72 },

	{ 288, 288 },
	{ 288, 72 },

	{ 144, 144 },
	{ 144, 72 },

	{ 72, 576 },
	{ 72, 288 },
	{ 72, 144 },
	{ 72, 72 },
    };
    unsigned int i;
    int n, num_ppi;
    const char *path = cairo_test_mkdir (CAIRO_TEST_OUTPUT_DIR) ? CAIRO_TEST_OUTPUT_DIR : ".";

    num_ppi = ARRAY_LENGTH (ppi);

#if GENERATE_REFERENCE
    for (n = 0; n < num_ppi; n++) {
	char *ref_name;
	xasprintf (&ref_name, "reference/fallback-resolution.ppi%gx%g.ref.png",
		   ppi[n].x, ppi[n].y);
	generate_reference (ppi[n].x, ppi[n].y, ref_name);
	free (ref_name);
    }
#endif

    for (i = 0; i < ctx->num_targets; i++) {
	const cairo_boilerplate_target_t *target = ctx->targets_to_test[i];
	cairo_surface_t *surface = NULL;
	char *base_name;
	void *closure;
	const char *format;
	cairo_status_t status;

	if (! target->is_vector)
	    continue;

	if (! cairo_test_is_target_enabled (ctx, target->name))
	    continue;

	format = cairo_boilerplate_content_name (target->content);
	xasprintf (&base_name, "%s/fallback-resolution.%s.%s",
		   path, target->name,
		   format);

	surface = (target->create_surface) (base_name,
					    target->content,
					    SIZE, SIZE,
					    SIZE, SIZE,
					    CAIRO_BOILERPLATE_MODE_TEST,
					    &closure);

	if (surface == NULL) {
	    free (base_name);
	    continue;
	}

	if (ret == CAIRO_TEST_UNTESTED)
	    ret = CAIRO_TEST_SUCCESS;

	cairo_surface_destroy (surface);
	if (target->cleanup)
	    target->cleanup (closure);
	free (base_name);

	/* we need to recreate the surface for each resolution as we include
	 * SVG in testing which does not support the paginated interface.
	 */
	for (n = 0; n < num_ppi; n++) {
	    char *test_name;
	    cairo_bool_t pass;

	    xasprintf (&test_name, "fallback-resolution.ppi%gx%g",
		       ppi[n].x, ppi[n].y);
	    xasprintf (&base_name, "%s/%s.%s.%s",
		       path, test_name,
		       target->name,
		       format);

	    surface = (target->create_surface) (base_name,
						target->content,
						SIZE + 25, SIZE + 25,
						SIZE + 25, SIZE + 25,
						CAIRO_BOILERPLATE_MODE_TEST,
						&closure);
	    if (surface == NULL || cairo_surface_status (surface)) {
		cairo_test_log (ctx, "Failed to generate surface: %s.%s\n",
				target->name,
				format);
		free (base_name);
		free (test_name);
		ret = CAIRO_TEST_FAILURE;
		continue;
	    }

	    cairo_test_log (ctx,
			    "Testing fallback-resolution %gx%g with %s target\n",
			    ppi[n].x, ppi[n].y, target->name);
	    printf ("%s:\t", base_name);
	    fflush (stdout);

	    if (target->force_fallbacks != NULL)
		target->force_fallbacks (surface, ppi[n].x, ppi[n].y);
	    cr = cairo_create (surface);
#if SET_TOLERANCE
	    cairo_set_tolerance (cr, 3.0);
#endif

	    cairo_surface_set_device_offset (surface, 25, 25);

	    cairo_save (cr); {
		cairo_set_source_rgb (cr, 1, 1, 1);
		cairo_paint (cr);
	    } cairo_restore (cr);

	    /* First draw the top half in a conventional way. */
	    cairo_save (cr); {
		cairo_rectangle (cr, 0, 0, SIZE, SIZE / 2.0);
		cairo_clip (cr);

		draw (cr, SIZE, SIZE);
	    } cairo_restore (cr);

	    /* Then draw the bottom half in a separate group,
	     * (exposing a bug in 1.6.4 with the group not being
	     * rendered with the correct fallback resolution). */
	    cairo_save (cr); {
		cairo_rectangle (cr, 0, SIZE / 2.0, SIZE, SIZE / 2.0);
		cairo_clip (cr);

		cairo_push_group (cr); {
		    draw (cr, SIZE, SIZE);
		} cairo_pop_group_to_source (cr);

		cairo_paint (cr);
	    } cairo_restore (cr);

	    status = cairo_status (cr);
	    cairo_destroy (cr);

	    pass = FALSE;
	    if (status) {
		cairo_test_log (ctx, "Error: Failed to create target surface: %s\n",
				cairo_status_to_string (status));
		ret = CAIRO_TEST_FAILURE;
	    } else {
		/* extract the image and compare it to our reference */
		if (! check_result (ctx, target, test_name, base_name, surface))
		    ret = CAIRO_TEST_FAILURE;
		else
		    pass = TRUE;
	    }
	    cairo_surface_destroy (surface);
	    if (target->cleanup)
		target->cleanup (closure);

	    free (base_name);
	    free (test_name);

	    if (pass) {
		printf ("PASS\n");
	    } else {
		printf ("FAIL\n");
	    }
	    fflush (stdout);
	}
    }

    return ret;
}
Exemplo n.º 6
0
static PyObject *
pycairo_pop_group_to_source (PycairoContext *o) {
  cairo_pop_group_to_source (o->ctx);
  Py_RETURN_NONE;
}
Exemplo n.º 7
0
void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int width, int /* offset */, const Color& color)
{
    if (paintingDisabled())
        return;

    unsigned rectCount = rects.size();

    cairo_t* cr = platformContext()->cr();
    cairo_save(cr);
    cairo_push_group(cr);
    cairo_new_path(cr);

#if PLATFORM(GTK)
#ifdef GTK_API_VERSION_2
    GdkRegion* reg = gdk_region_new();
#else
    cairo_region_t* reg = cairo_region_create();
#endif

    for (unsigned i = 0; i < rectCount; i++) {
#ifdef GTK_API_VERSION_2
        GdkRectangle rect = rects[i];
        gdk_region_union_with_rect(reg, &rect);
#else
        cairo_rectangle_int_t rect = rects[i];
        cairo_region_union_rectangle(reg, &rect);
#endif
    }
    gdk_cairo_region(cr, reg);
#ifdef GTK_API_VERSION_2
    gdk_region_destroy(reg);
#else
    cairo_region_destroy(reg);
#endif
#else
    int radius = (width - 1) / 2;
    Path path;
    for (unsigned i = 0; i < rectCount; ++i) {
        if (i > 0)
            path.clear();
        path.addRoundedRect(rects[i], FloatSize(radius, radius));
        appendWebCorePathToCairoContext(cr, path);
    }
#endif
    Color ringColor = color;
    adjustFocusRingColor(ringColor);
    adjustFocusRingLineWidth(width);
    setSourceRGBAFromColor(cr, ringColor);
    cairo_set_line_width(cr, width);
    setPlatformStrokeStyle(focusRingStrokeStyle());

    cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
    cairo_stroke_preserve(cr);

    cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
    cairo_set_fill_rule(cr, CAIRO_FILL_RULE_WINDING);
    cairo_fill(cr);

    cairo_pop_group_to_source(cr);
    cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
    cairo_paint(cr);
    cairo_restore(cr);
}
Exemplo n.º 8
0
	void lime_cairo_pop_group_to_source (value handle) {
		
		cairo_pop_group_to_source ((cairo_t*)val_data (handle));
		
	}