Size Border::MeasureOverrideWithError (Size availableSize, MoonError *error) { Size desired = Size (0,0); Thickness border = *GetPadding () + *GetBorderThickness (); // Get the desired size of our child, and include any margins we set VisualTreeWalker walker = VisualTreeWalker (this); while (UIElement *child = walker.Step ()) { child->MeasureWithError (availableSize.GrowBy (-border), error); desired = child->GetDesiredSize (); } desired = desired.GrowBy (border); desired = desired.Min (availableSize); return desired; }
void Image::Render (cairo_t *cr, Region *region, bool path_only) { ImageSource *source = GetSource (); cairo_pattern_t *pattern = NULL; cairo_matrix_t matrix; if (!source) return; source->Lock (); cairo_save (cr); Size specified (GetActualWidth (), GetActualHeight ()); Size stretched = ApplySizeConstraints (specified); bool adjust = specified != GetRenderSize (); if (GetStretch () != StretchUniformToFill) specified = specified.Min (stretched); Rect paint = Rect (0, 0, specified.width, specified.height); if (!path_only) { Rect image = Rect (0, 0, source->GetPixelWidth (), source->GetPixelHeight ()); if (GetStretch () == StretchNone) paint = paint.Union (image); if (image.width == 0.0 && image.height == 0.0) goto cleanup; pattern = cairo_pattern_create_for_surface (source->GetSurface (cr)); image_brush_compute_pattern_matrix (&matrix, paint.width, paint.height, image.width, image.height, GetStretch (), AlignmentXCenter, AlignmentYCenter, NULL, NULL); cairo_pattern_set_matrix (pattern, &matrix); #if MAKE_EVERYTHING_SLOW_AND_BUGGY cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD); #endif if (cairo_pattern_status (pattern) == CAIRO_STATUS_SUCCESS) { cairo_set_source (cr, pattern); } cairo_pattern_destroy (pattern); } if (adjust) { // FIXME: Propagate error properly MoonError error; specified = MeasureOverrideWithError (specified, &error); paint = Rect ((stretched.width - specified.width) * 0.5, (stretched.height - specified.height) * 0.5, specified.width, specified.height); } if (!path_only) RenderLayoutClip (cr); paint = paint.Intersection (Rect (0, 0, stretched.width, stretched.height)); paint.Draw (cr); if (!path_only) cairo_fill (cr); cleanup: cairo_restore (cr); source->Unlock (); }