예제 #1
0
파일: media.cpp 프로젝트: snorp/moon
Rect
Image::GetCoverageBounds ()
{
	// FIXME: SL3 final only supports PixelFormatPbgra32 which makes this optimization
	// obsolete - unless we keep an "has_alpha" flag with each image ?!?
	return Rect ();
#if FALSE
	ImageSource *source = GetSource ();

	if (!source || source->GetPixelFormat () == PixelFormatPbgra32)
		return Rect ();

	Stretch stretch = GetStretch ();
	if (stretch == StretchFill || stretch == StretchUniformToFill)
		return bounds;

	cairo_matrix_t matrix;
	Rect image = Rect (0, 0, source->GetPixelWidth (), source->GetPixelHeight ());
	Rect paint = Rect (0, 0, GetActualWidth (), GetActualHeight ());

	image_brush_compute_pattern_matrix (&matrix, 
					    paint.width, paint.height,
					    image.width, image.height, stretch, 
					    AlignmentXCenter, AlignmentYCenter, NULL, NULL);

	cairo_matrix_invert (&matrix);
	cairo_matrix_multiply (&matrix, &matrix, &absolute_xform);

	image = image.Transform (&matrix);
	image = image.Intersection (bounds);
	
	return image;
#endif
}
예제 #2
0
파일: media.cpp 프로젝트: snorp/moon
Size
Image::MeasureOverrideWithError (Size availableSize, MoonError *error)
{
	Size desired = availableSize;
	Rect shape_bounds = Rect ();
	ImageSource *source = GetSource ();
	double sx = 0.0;
	double sy = 0.0;

	if (source)
		shape_bounds = Rect (0,0,source->GetPixelWidth (),source->GetPixelHeight ());

	/* don't stretch to infinite size */
	if (isinf (desired.width))
		desired.width = shape_bounds.width;
	if (isinf (desired.height))
		desired.height = shape_bounds.height;
	
	/* compute the scaling */
	if (shape_bounds.width > 0)
		sx = desired.width / shape_bounds.width;
	if (shape_bounds.height > 0)
		sy = desired.height / shape_bounds.height;

	/* don't use infinite dimensions as constraints */
	if (isinf (availableSize.width))
		sx = sy;
	if (isinf (availableSize.height))
		sy = sx;

	switch (GetStretch ()) {
	case StretchUniform:
		sx = sy = MIN (sx, sy);
		break;
	case StretchUniformToFill:
		sx = sy = MAX (sx, sy);
		break;
	case StretchFill:
		if (isinf (availableSize.width))
			sx = sy;
		if (isinf (availableSize.height))
			sy = sx;
		break;
	case StretchNone:
		sx = sy = 1.0;
		break;
	}

	desired = Size (shape_bounds.width * sx, shape_bounds.height * sy);

	return desired;
}
예제 #3
0
파일: media.cpp 프로젝트: snorp/moon
void
Image::OnPropertyChanged (PropertyChangedEventArgs *args, MoonError *error)
{
	if (args->GetProperty ()->GetOwnerType() != Type::IMAGE) {
		MediaBase::OnPropertyChanged (args, error);
		return;
	}
	
	if (args->GetId () == Image::SourceProperty) {
		ImageSource *source = args->GetNewValue () ? args->GetNewValue ()->AsImageSource () : NULL; 
		ImageSource *old = args->GetOldValue () ? args->GetOldValue ()->AsImageSource () : NULL;

		if (old) {
			if (old->Is(Type::BITMAPSOURCE)) {
				old->RemoveHandler (BitmapSource::PixelDataChangedEvent, source_pixel_data_changed, this);
			}

			if (old->Is(Type::BITMAPIMAGE)) {
				old->RemoveHandler (BitmapImage::DownloadProgressEvent, download_progress, this);
				old->RemoveHandler (BitmapImage::ImageOpenedEvent, image_opened, this);
				old->RemoveHandler (BitmapImage::ImageFailedEvent, image_failed, this);
			}			
		}
		
		if (source) {
			if (source->Is(Type::BITMAPSOURCE)) {
				source->AddHandler (BitmapSource::PixelDataChangedEvent, source_pixel_data_changed, this);
			}

		        if (source->Is(Type::BITMAPIMAGE)) {
				source->AddHandler (BitmapImage::DownloadProgressEvent, download_progress, this);
				source->AddHandler (BitmapImage::ImageOpenedEvent, image_opened, this);
				source->AddHandler (BitmapImage::ImageFailedEvent, image_failed, this);
			}

			if (source->GetPixelWidth () > 0 && source->GetPixelHeight () > 0) {
				RoutedEventArgs *args = MoonUnmanagedFactory::CreateRoutedEventArgs ();
				ImageOpened (args);
				args->unref ();
			}
		} else {
			UpdateBounds ();
			Invalidate ();
		}

		InvalidateMeasure ();
	}
	
	// we need to notify attachees if our DownloadProgress changed.
	NotifyListenersOfPropertyChange (args, error);
}
예제 #4
0
파일: media.cpp 프로젝트: snorp/moon
Size
Image::ArrangeOverrideWithError (Size finalSize, MoonError *error)
{
	Size arranged = finalSize;
	Rect shape_bounds = Rect ();
	ImageSource *source = GetSource ();
	double sx = 1.0;
	double sy = 1.0;

	if (source)
		shape_bounds = Rect (0, 0, source->GetPixelWidth (), source->GetPixelHeight ());

	/* compute the scaling */
	if (shape_bounds.width == 0)
		shape_bounds.width = arranged.width;
	if (shape_bounds.height == 0)
		shape_bounds.height = arranged.height;

	if (shape_bounds.width != arranged.width)
		sx = arranged.width / shape_bounds.width;
	if (shape_bounds.height != arranged.height)
		sy = arranged.height / shape_bounds.height;

	switch (GetStretch ()) {
	case StretchUniform:
		sx = sy = MIN (sx, sy);
		break;
	case StretchUniformToFill:
		sx = sy = MAX (sx, sy);
		break;
	case StretchNone:
		sx = sy = 1.0;
	default:
		break;
	}

	arranged = Size (shape_bounds.width * sx, shape_bounds.height * sy);

	return arranged;
}
예제 #5
0
파일: media.cpp 프로젝트: snorp/moon
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 ();
}