Index: uielement.h =================================================================== --- uielement.h (revision 94509) +++ uielement.h (working copy) @@ -68,7 +68,8 @@ SHAPE_EMPTY = 0x20, // there's is nothing to draw, the cached path may be NULL SHAPE_NORMAL = 0x40, // normal drawing SHAPE_DEGENERATE = 0x80, // degenerate drawing, use the Stroke brush for filling - SHAPE_MASK = (SHAPE_EMPTY | SHAPE_NORMAL | SHAPE_DEGENERATE) + SHAPE_RADII = 0x100, + SHAPE_MASK = (SHAPE_EMPTY | SHAPE_NORMAL | SHAPE_DEGENERATE | SHAPE_RADII) }; int flags; Index: shape.cpp =================================================================== --- shape.cpp (revision 94509) +++ shape.cpp (working copy) @@ -499,6 +499,12 @@ } } +Rect +Shape::ComputeLargestRectangle () +{ + return Rect (); +} + Brush * shape_get_fill (Shape *shape) { @@ -763,6 +769,15 @@ // note: both moon_rounded_rectangle and moon_ellipse close the path } +Rect +Ellipse::ComputeLargestRectangle () +{ + double t = GetValue (Shape::StrokeThicknessProperty)->AsDouble (); + double x = (GetValue (FrameworkElement::WidthProperty)->AsDouble () - t) * cos (M_PI_2); + double y = (GetValue (FrameworkElement::HeightProperty)->AsDouble () - t) * sin (M_PI_2); + return bounds.GrowBy (-x, -y).RoundIn (); +} + void Ellipse::OnPropertyChanged (DependencyProperty *prop) { @@ -809,8 +824,8 @@ if (!SetupLine (cr)) return drawn; - // FIXME: is it worth checking for round-corners ? - SetupLineJoinMiter (cr); + if (!HasRadii ()) + SetupLineJoinMiter (cr); // Draw if the path wasn't drawn by the Fill call if (!drawn) @@ -899,7 +914,7 @@ radius_x = radius_y = t / 2; break; } - SetShapeFlags (UIElement::SHAPE_DEGENERATE); + SetShapeFlags (round ? (UIElementFlags)(UIElement::SHAPE_DEGENERATE | UIElement::SHAPE_RADII) : UIElement::SHAPE_DEGENERATE); goto shape; } else { // (b) the thickness is larger (or equal) to half the width or half the height @@ -916,7 +931,7 @@ radius_y = h; } } - SetShapeFlags (UIElement::SHAPE_DEGENERATE); + SetShapeFlags (round ? (UIElementFlags)(UIElement::SHAPE_DEGENERATE | UIElement::SHAPE_RADII) : UIElement::SHAPE_DEGENERATE); goto shape; } } @@ -954,7 +969,7 @@ if (compute_origin && (!IsStroked () || (t != 1.0))) x = y = t / 2.0; - SetShapeFlags (UIElement::SHAPE_NORMAL); + SetShapeFlags (round ? (UIElementFlags)(UIElement::SHAPE_NORMAL | UIElement::SHAPE_RADII) : UIElement::SHAPE_NORMAL); shape: // rounded-corner rectangle ? @@ -1004,10 +1019,22 @@ return ((*rx != 0.0) && (*ry != 0.0)); } +Rect +Rectangle::ComputeLargestRectangle () +{ + double x = GetValue (Shape::StrokeThicknessProperty)->AsDouble (); + double y = x; + if (HasRadii ()) { + x += GetValue (Rectangle::RadiusXProperty)->AsDouble (); + y += GetValue (Rectangle::RadiusYProperty)->AsDouble (); + } + return bounds.GrowBy (-x, -y).RoundIn (); +} + double rectangle_get_radius_x (Rectangle *rectangle) { - return rectangle->GetValue (Rectangle::RadiusXProperty)->AsDouble(); + return rectangle->GetValue (Rectangle::RadiusXProperty)->AsDouble (); } void Index: shape.h =================================================================== --- shape.h (revision 94509) +++ shape.h (working copy) @@ -71,6 +71,7 @@ virtual void Render (cairo_t *cr, int x, int y, int width, int height); virtual void GetSizeForBrush (cairo_t *cr, double *width, double *height); virtual void ComputeBounds (); + virtual Rect ComputeLargestRectangle (); virtual bool InsideObject (cairo_t *cr, double x, double y); virtual Point GetTransformOrigin (); @@ -103,6 +104,7 @@ bool IsEmpty () { return (flags & UIElement::SHAPE_EMPTY); }; bool IsNormal () { return (flags & UIElement::SHAPE_NORMAL); }; bool IsDegenerate () { return (flags & UIElement::SHAPE_DEGENERATE); }; + bool HasRadii () { return (flags & UIElement::SHAPE_RADII); }; void SetShapeFlags (UIElementFlags sf) { flags &= ~UIElement::SHAPE_MASK; flags |= sf; }; }; @@ -141,6 +143,7 @@ virtual Type::Kind GetObjectType () { return Type::ELLIPSE; }; virtual void BuildPath (); + virtual Rect ComputeLargestRectangle (); virtual bool CanFill () { return true; } virtual void OnPropertyChanged (DependencyProperty *prop); @@ -163,6 +166,7 @@ virtual Type::Kind GetObjectType () { return Type::RECTANGLE; }; virtual void BuildPath (); + virtual Rect ComputeLargestRectangle (); virtual void OnPropertyChanged (DependencyProperty *prop);