+// Draw the borders and background for the given rectangle and attributes.
+// Width and height are taken to be the content size, so excluding any
+// border, margin and padding.
+bool wxRichTextObject::DrawBoxAttributes(wxDC& dc, const wxRichTextAttr& attr, const wxRect& boxRect)
+{
+ // Assume boxRect is the area around the content
+ wxRect contentRect = boxRect;
+ wxRect marginRect, borderRect, paddingRect, outlineRect;
+
+ GetBoxRects(dc, attr, marginRect, borderRect, contentRect, paddingRect, outlineRect);
+
+ // Margin is transparent. Draw background from margin.
+ if (attr.HasBackgroundColour())
+ {
+ wxPen pen(attr.GetBackgroundColour());
+ wxBrush brush(attr.GetBackgroundColour());
+
+ dc.SetPen(pen);
+ dc.SetBrush(brush);
+ dc.DrawRectangle(marginRect);
+ }
+
+ if (attr.GetTextBoxAttr().GetBorder().HasBorder())
+ DrawBorder(dc, attr.GetTextBoxAttr().GetBorder(), borderRect);
+
+ if (attr.GetTextBoxAttr().GetOutline().HasBorder())
+ DrawBorder(dc, attr.GetTextBoxAttr().GetOutline(), outlineRect);
+
+ return true;
+}
+
+// Draw a border
+bool wxRichTextObject::DrawBorder(wxDC& dc, const wxTextAttrBorders& attr, const wxRect& rect)
+{
+ int borderLeft = 0, borderRight = 0, borderTop = 0, borderBottom = 0;
+ wxTextAttrDimensionConverter converter(dc);
+
+ if (attr.GetLeft().IsValid())
+ {
+ borderLeft = converter.GetPixels(attr.GetLeft().GetWidth());
+ wxColour col(attr.GetLeft().GetColour());
+
+ // If pen width is > 1, resorts to a solid rectangle.
+ if (borderLeft == 1)
+ {
+ int penStyle = wxSOLID;
+ if (attr.GetLeft().GetStyle() == wxTEXT_BOX_ATTR_BORDER_DOTTED)
+ penStyle = wxDOT;
+ else if (attr.GetLeft().GetStyle() == wxTEXT_BOX_ATTR_BORDER_DASHED)
+ penStyle = wxLONG_DASH;
+ wxPen pen(col);
+ dc.SetPen(pen);
+ dc.DrawLine(rect.x, rect.y, rect.x, rect.y + rect.height);
+
+ }
+ else if (borderLeft > 1)
+ {
+ wxPen pen(col);
+ wxBrush brush(col);
+ dc.SetPen(pen);
+ dc.SetBrush(brush);
+ dc.DrawRectangle(rect.x, rect.y, borderLeft, rect.height);
+ }
+ }
+
+ if (attr.GetRight().IsValid())
+ {
+ borderRight = converter.GetPixels(attr.GetRight().GetWidth());
+
+ wxColour col(attr.GetRight().GetColour());
+
+ // If pen width is > 1, resorts to a solid rectangle.
+ if (borderRight == 1)
+ {
+ int penStyle = wxSOLID;
+ if (attr.GetRight().GetStyle() == wxTEXT_BOX_ATTR_BORDER_DOTTED)
+ penStyle = wxDOT;
+ else if (attr.GetRight().GetStyle() == wxTEXT_BOX_ATTR_BORDER_DASHED)
+ penStyle = wxLONG_DASH;
+ wxPen pen(col);
+ dc.SetPen(pen);
+ dc.DrawLine(rect.x + rect.width, rect.y, rect.x + rect.width, rect.y + rect.height);
+
+ }
+ else if (borderRight > 1)
+ {
+ wxPen pen(col);
+ wxBrush brush(col);
+ dc.SetPen(pen);
+ dc.SetBrush(brush);
+ dc.DrawRectangle(rect.x - borderRight, rect.y, borderRight, rect.height);
+ }
+ }
+
+ if (attr.GetTop().IsValid())
+ {
+ borderTop = converter.GetPixels(attr.GetTop().GetWidth());
+
+ wxColour col(attr.GetTop().GetColour());
+
+ // If pen width is > 1, resorts to a solid rectangle.
+ if (borderTop == 1)
+ {
+ int penStyle = wxSOLID;
+ if (attr.GetTop().GetStyle() == wxTEXT_BOX_ATTR_BORDER_DOTTED)
+ penStyle = wxDOT;
+ else if (attr.GetTop().GetStyle() == wxTEXT_BOX_ATTR_BORDER_DASHED)
+ penStyle = wxLONG_DASH;
+ wxPen pen(col);
+ dc.SetPen(pen);
+ dc.DrawLine(rect.x, rect.y, rect.x + rect.width, rect.y);
+
+ }
+ else if (borderTop > 1)
+ {
+ wxPen pen(col);
+ wxBrush brush(col);
+ dc.SetPen(pen);
+ dc.SetBrush(brush);
+ dc.DrawRectangle(rect.x, rect.y, rect.width, borderTop);
+ }
+ }
+
+ if (attr.GetBottom().IsValid())
+ {
+ borderBottom = converter.GetPixels(attr.GetBottom().GetWidth());
+ wxColour col(attr.GetTop().GetColour());
+
+ // If pen width is > 1, resorts to a solid rectangle.
+ if (borderBottom == 1)
+ {
+ int penStyle = wxSOLID;
+ if (attr.GetBottom().GetStyle() == wxTEXT_BOX_ATTR_BORDER_DOTTED)
+ penStyle = wxDOT;
+ else if (attr.GetBottom().GetStyle() == wxTEXT_BOX_ATTR_BORDER_DASHED)
+ penStyle = wxLONG_DASH;
+ wxPen pen(col);
+ dc.SetPen(pen);
+ dc.DrawLine(rect.x, rect.y + rect.height, rect.x + rect.width, rect.y + rect.height);
+
+ }
+ else if (borderBottom > 1)
+ {
+ wxPen pen(col);
+ wxBrush brush(col);
+ dc.SetPen(pen);
+ dc.SetBrush(brush);
+ dc.DrawRectangle(rect.x, rect.y - rect.height - borderBottom, rect.width, borderBottom);
+ }
+ }
+
+ return true;
+}
+
+// Get the various rectangles of the box model in pixels. You can either specify contentRect (inner)
+// or marginRect (outer), and the other must be the default rectangle (no width or height).
+// Note that the outline doesn't affect the position of the rectangle, it's drawn in whatever space
+// is available.
+//
+// | Margin | Border | Padding | CONTENT | Padding | Border | Margin |
+
+bool wxRichTextObject::GetBoxRects(wxDC& dc, const wxRichTextAttr& attr, wxRect& marginRect, wxRect& borderRect, wxRect& contentRect, wxRect& paddingRect, wxRect& outlineRect)
+{
+ int borderLeft = 0, borderRight = 0, borderTop = 0, borderBottom = 0;
+ int outlineLeft = 0, outlineRight = 0, outlineTop = 0, outlineBottom = 0;
+ int paddingLeft = 0, paddingRight = 0, paddingTop = 0, paddingBottom = 0;
+ int marginLeft = 0, marginRight = 0, marginTop = 0, marginBottom = 0;
+
+ wxTextAttrDimensionConverter converter(dc);
+
+ if (attr.GetTextBoxAttr().GetMargins().GetLeft().IsPresent())
+ marginLeft = converter.GetPixels(attr.GetTextBoxAttr().GetMargins().GetLeft());
+ if (attr.GetTextBoxAttr().GetMargins().GetRight().IsPresent())
+ marginRight = converter.GetPixels(attr.GetTextBoxAttr().GetMargins().GetRight());
+ if (attr.GetTextBoxAttr().GetMargins().GetTop().IsPresent())
+ marginTop = converter.GetPixels(attr.GetTextBoxAttr().GetMargins().GetTop());
+ if (attr.GetTextBoxAttr().GetMargins().GetLeft().IsPresent())
+ marginBottom = converter.GetPixels(attr.GetTextBoxAttr().GetMargins().GetBottom());
+
+ if (attr.GetTextBoxAttr().GetBorder().GetLeft().GetWidth().IsPresent())
+ borderLeft = converter.GetPixels(attr.GetTextBoxAttr().GetBorder().GetLeft().GetWidth());
+ if (attr.GetTextBoxAttr().GetBorder().GetRight().GetWidth().IsPresent())
+ borderRight = converter.GetPixels(attr.GetTextBoxAttr().GetBorder().GetRight().GetWidth());
+ if (attr.GetTextBoxAttr().GetBorder().GetTop().GetWidth().IsPresent())
+ borderTop = converter.GetPixels(attr.GetTextBoxAttr().GetBorder().GetTop().GetWidth());
+ if (attr.GetTextBoxAttr().GetBorder().GetLeft().GetWidth().IsPresent())
+ borderBottom = converter.GetPixels(attr.GetTextBoxAttr().GetBorder().GetBottom().GetWidth());
+
+ if (attr.GetTextBoxAttr().GetPadding().GetLeft().IsPresent())
+ paddingLeft = converter.GetPixels(attr.GetTextBoxAttr().GetPadding().GetLeft());
+ if (attr.GetTextBoxAttr().GetPadding().GetRight().IsPresent())
+ paddingRight = converter.GetPixels(attr.GetTextBoxAttr().GetPadding().GetRight());
+ if (attr.GetTextBoxAttr().GetPadding().GetTop().IsPresent())
+ paddingTop = converter.GetPixels(attr.GetTextBoxAttr().GetPadding().GetTop());
+ if (attr.GetTextBoxAttr().GetPadding().GetLeft().IsPresent())
+ paddingBottom = converter.GetPixels(attr.GetTextBoxAttr().GetPadding().GetBottom());
+
+ if (attr.GetTextBoxAttr().GetOutline().GetLeft().GetWidth().IsPresent())
+ outlineLeft = converter.GetPixels(attr.GetTextBoxAttr().GetOutline().GetLeft().GetWidth());
+ if (attr.GetTextBoxAttr().GetOutline().GetRight().GetWidth().IsPresent())
+ outlineRight = converter.GetPixels(attr.GetTextBoxAttr().GetOutline().GetRight().GetWidth());
+ if (attr.GetTextBoxAttr().GetOutline().GetTop().GetWidth().IsPresent())
+ outlineTop = converter.GetPixels(attr.GetTextBoxAttr().GetOutline().GetTop().GetWidth());
+ if (attr.GetTextBoxAttr().GetOutline().GetLeft().GetWidth().IsPresent())
+ outlineBottom = converter.GetPixels(attr.GetTextBoxAttr().GetOutline().GetBottom().GetWidth());
+
+ int leftTotal = marginLeft + borderLeft + paddingLeft;
+ int rightTotal = marginRight + borderRight + paddingRight;
+ int topTotal = marginTop + borderTop + paddingTop;
+ int bottomTotal = marginBottom + borderBottom + paddingBottom;
+
+ if (marginRect != wxRect())
+ {
+ contentRect.x = marginRect.x + leftTotal;
+ contentRect.y = marginRect.y + topTotal;
+ contentRect.width = marginRect.width - (leftTotal + rightTotal);
+ contentRect.height = marginRect.height - (topTotal + bottomTotal);
+ }
+ else
+ {
+ marginRect.x = contentRect.x - leftTotal;
+ marginRect.y = contentRect.y - topTotal;
+ marginRect.width = contentRect.width + (leftTotal + rightTotal);
+ marginRect.height = contentRect.height + (topTotal + bottomTotal);
+ }
+
+ borderRect.x = marginRect.x + marginLeft;
+ borderRect.y = marginRect.y + marginTop;
+ borderRect.width = marginRect.width - (marginLeft + marginRight);
+ borderRect.height = marginRect.height - (marginTop + marginBottom);
+
+ paddingRect.x = marginRect.x + marginLeft + borderLeft;
+ paddingRect.y = marginRect.y + marginTop + borderTop;
+ paddingRect.width = marginRect.width - (marginLeft + marginRight + borderLeft + borderRight);
+ paddingRect.height = marginRect.height - (marginTop + marginBottom + borderTop + borderBottom);
+
+ // The outline is outside the margin and doesn't influence the overall box position or content size.
+ outlineRect.x = marginRect.x - outlineLeft;
+ outlineRect.y = marginRect.y - outlineTop;
+ outlineRect.width = marginRect.width + (outlineLeft + outlineRight);
+ outlineRect.height = marginRect.height + (outlineTop + outlineBottom);
+
+ return true;
+}
+
+