[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: KDE/kdelibs/khtml/rendering
From: Fredrik Höglund <fredrik () kde ! org>
Date: 2008-12-04 20:13:35
Message-ID: 1228421615.305038.13295.nullmailer () svn ! kde ! org
[Download RAW message or body]
SVN commit 892640 by fredrik:
Update the handling of overlapping border radii to comply with the
latest WD of the CSS3 spec.
M +117 -118 render_object.cpp
M +2 -0 render_object.h
--- trunk/KDE/kdelibs/khtml/rendering/render_object.cpp #892639:892640
@@ -1185,6 +1185,34 @@
p->setCompositionMode(QPainter::CompositionMode_SourceOver);
}
+void RenderObject::adjustBorderRadii(BorderRadii &tl, BorderRadii &tr, BorderRadii \
&bl, BorderRadii &br, int w, int h) const +{
+ // CSS Backgrounds and Borders Module Level 3 (WD-css3-background-20080910), \
chapter 4.5: + // " Corners do not overlap: When the sum of two adjacent corner \
radii exceeds the size of the border box, + // UAs must reduce one or more of the \
radii. The algorithm for reducing radii is as follows:" + // The sum of two \
adjacent radii may not be more than the width or height (whichever is relevant) of \
the box. + // If any sum exceeds that value, all radii are reduced according to \
the following formula:" + const int horS = qMax(tl.horizontal + tr.horizontal, \
bl.horizontal + br.horizontal); + const int verS = qMax(tl.vertical + bl.vertical, \
tr.vertical + br.vertical); +
+ qreal f = 1.0;
+ if (horS > 0)
+ f = qMin(f, w / qreal(horS));
+ if (verS > 0)
+ f = qMin(f, h / qreal(verS));
+
+ if (f < 1.0) {
+ tl.horizontal *= f;
+ tr.horizontal *= f;
+ bl.horizontal *= f;
+ br.horizontal *= f;
+ tl.vertical *= f;
+ tr.vertical *= f;
+ bl.vertical *= f;
+ br.vertical *= f;
+ }
+}
+
static QImage blendCornerImages(const QImage &image1, const QImage &image2)
{
QImage mask(image1.size(), QImage::Format_ARGB32_Premultiplied);
@@ -1386,21 +1414,16 @@
bool render_r = rs > BHIDDEN && end && !rt;
bool render_b = bs > BHIDDEN && !bt;
- // Need sufficient width and height to contain border radius curves. Sanity \
check our border radii
- // and our width/height values to make sure the curves can all fit. If not, then \
we won't paint
- // any border radii.
- bool renderRadii = false;
BorderRadii topLeft = style->borderTopLeftRadius();
BorderRadii topRight = style->borderTopRightRadius();
BorderRadii bottomLeft = style->borderBottomLeftRadius();
BorderRadii bottomRight = style->borderBottomRightRadius();
- if (style->hasBorderRadius() &&
- static_cast<unsigned>(w) >= static_cast<unsigned>(topLeft.horizontal) + \
static_cast<unsigned>(topRight.horizontal) &&
- static_cast<unsigned>(w) >= static_cast<unsigned>(bottomLeft.horizontal) + \
static_cast<unsigned>(bottomRight.horizontal) &&
- static_cast<unsigned>(h) >= static_cast<unsigned>(topLeft.vertical) + \
static_cast<unsigned>(bottomLeft.vertical) &&
- static_cast<unsigned>(h) >= static_cast<unsigned>(topRight.vertical) + \
static_cast<unsigned>(bottomRight.vertical))
- renderRadii = true;
+ if (style->hasBorderRadius()) {
+ // Adjust the border radii so they don't overlap when taking the size of the \
box + // into account.
+ adjustBorderRadii(topLeft, topRight, bottomLeft, bottomRight, w, h);
+ }
bool upperLeftBorderStylesMatch = render_l && (ts == ls) && (tc == lc);
bool upperRightBorderStylesMatch = render_r && (ts == rs) && (tc == rc);
@@ -1408,190 +1431,166 @@
bool lowerRightBorderStylesMatch = render_r && (bs == rs) && (bc == rc);
if(render_t) {
- bool ignore_left = (renderRadii && topLeft.horizontal > 0) ||
+ bool ignore_left = (topLeft.horizontal > 0) ||
((tc == lc) && (tt == lt) &&
(ts >= OUTSET) &&
(ls == DOTTED || ls == DASHED || ls == SOLID || ls == OUTSET));
- bool ignore_right = (renderRadii && topRight.horizontal > 0) ||
+ bool ignore_right = (topRight.horizontal > 0) ||
((tc == rc) && (tt == rt) &&
(ts >= OUTSET) &&
(rs == DOTTED || rs == DASHED || rs == SOLID || rs == INSET));
- int x = _tx;
- int x2 = _tx + w;
- if (renderRadii) {
- x += topLeft.horizontal;
- x2 -= topRight.horizontal;
- }
+ int x = _tx + topLeft.horizontal;
+ int x2 = _tx + w - topRight.horizontal;
drawBorder(p, x, _ty, x2, _ty + style->borderTopWidth(), BSTop, tc, \
style->color(), ts, ignore_left?0:style->borderLeftWidth(),
ignore_right?0:style->borderRightWidth());
- if (renderRadii) {
- if (topLeft.hasBorderRadius()) {
- int x = _tx + topLeft.horizontal;
- int y = _ty + topLeft.vertical;
- int startAngle = 90;
- int span = upperLeftBorderStylesMatch ? 90 : 45;
+ if (topLeft.hasBorderRadius()) {
+ int x = _tx + topLeft.horizontal;
+ int y = _ty + topLeft.vertical;
+ int startAngle = 90;
+ int span = upperLeftBorderStylesMatch ? 90 : 45;
- // Draw the upper left arc
- drawBorderArc(p, x, y, style->borderLeftWidth(), \
style->borderTopWidth(),
- topLeft, startAngle, span, tc, style->color(), ts);
- }
+ // Draw the upper left arc
+ drawBorderArc(p, x, y, style->borderLeftWidth(), \
style->borderTopWidth(), + topLeft, startAngle, span, tc, \
style->color(), ts); + }
- if (topRight.hasBorderRadius()) {
- int x = _tx + w - topRight.horizontal;
- int y = _ty + topRight.vertical;
- int startAngle = 90;
- int span = upperRightBorderStylesMatch ? -90 : -45;
+ if (topRight.hasBorderRadius()) {
+ int x = _tx + w - topRight.horizontal;
+ int y = _ty + topRight.vertical;
+ int startAngle = 90;
+ int span = upperRightBorderStylesMatch ? -90 : -45;
- // Draw the upper right arc
- drawBorderArc(p, x, y, style->borderRightWidth(), \
style->borderTopWidth(),
- topRight, startAngle, span, tc, style->color(), ts);
- }
+ // Draw the upper right arc
+ drawBorderArc(p, x, y, style->borderRightWidth(), \
style->borderTopWidth(), + topRight, startAngle, span, tc, \
style->color(), ts); }
}
if(render_b) {
- bool ignore_left = (renderRadii && bottomLeft.horizontal > 0) ||
+ bool ignore_left = (bottomLeft.horizontal > 0) ||
((bc == lc) && (bt == lt) &&
(bs >= OUTSET) &&
(ls == DOTTED || ls == DASHED || ls == SOLID || ls == OUTSET));
- bool ignore_right = (renderRadii && bottomRight.horizontal > 0) ||
+ bool ignore_right = (bottomRight.horizontal > 0) ||
((bc == rc) && (bt == rt) &&
(bs >= OUTSET) &&
(rs == DOTTED || rs == DASHED || rs == SOLID || rs == INSET));
- int x = _tx;
- int x2 = _tx + w;
- if (renderRadii) {
- x += bottomLeft.horizontal;
- x2 -= bottomRight.horizontal;
- }
+ int x = _tx + bottomLeft.horizontal;
+ int x2 = _tx + w - bottomRight.horizontal;
drawBorder(p, x, _ty + h - style->borderBottomWidth(), x2, _ty + h, \
BSBottom, bc, style->color(), bs, ignore_left?0:style->borderLeftWidth(),
ignore_right?0:style->borderRightWidth());
- if (renderRadii) {
- if (bottomLeft.hasBorderRadius()) {
- int x = _tx + bottomLeft.horizontal;
- int y = _ty + h - bottomLeft.vertical;
- int startAngle = 270;
- int span = lowerLeftBorderStylesMatch ? -90 : -45;
+ if (bottomLeft.hasBorderRadius()) {
+ int x = _tx + bottomLeft.horizontal;
+ int y = _ty + h - bottomLeft.vertical;
+ int startAngle = 270;
+ int span = lowerLeftBorderStylesMatch ? -90 : -45;
- // Draw the bottom left arc
- drawBorderArc(p, x, y, style->borderLeftWidth(), \
style->borderBottomWidth(),
- bottomLeft, startAngle, span, bc, style->color(), bs);
- }
+ // Draw the bottom left arc
+ drawBorderArc(p, x, y, style->borderLeftWidth(), \
style->borderBottomWidth(), + bottomLeft, startAngle, span, \
bc, style->color(), bs); + }
- if (bottomRight.hasBorderRadius()) {
- int x = _tx + w - bottomRight.horizontal;
- int y = _ty + h - bottomRight.vertical;
- int startAngle = 270;
- int span = lowerRightBorderStylesMatch ? 90 : 45;
+ if (bottomRight.hasBorderRadius()) {
+ int x = _tx + w - bottomRight.horizontal;
+ int y = _ty + h - bottomRight.vertical;
+ int startAngle = 270;
+ int span = lowerRightBorderStylesMatch ? 90 : 45;
- // Draw the bottom right arc
- drawBorderArc(p, x, y, style->borderRightWidth(), \
style->borderBottomWidth(),
- bottomRight, startAngle, span, bc, style->color(), \
bs);
- }
+ // Draw the bottom right arc
+ drawBorderArc(p, x, y, style->borderRightWidth(), \
style->borderBottomWidth(), + bottomRight, startAngle, span, \
bc, style->color(), bs); }
}
if(render_l)
{
- bool ignore_top = (renderRadii && topLeft.vertical > 0) ||
+ bool ignore_top = (topLeft.vertical > 0) ||
((tc == lc) && (tt == lt) &&
(ls >= OUTSET) &&
(ts == DOTTED || ts == DASHED || ts == SOLID || ts == OUTSET));
- bool ignore_bottom = (renderRadii && bottomLeft.vertical > 0) ||
+ bool ignore_bottom = (bottomLeft.vertical > 0) ||
((bc == lc) && (bt == lt) &&
(ls >= OUTSET) &&
(bs == DOTTED || bs == DASHED || bs == SOLID || bs == INSET));
- int y = _ty;
- int y2 = _ty + h;
- if (renderRadii) {
- y += topLeft.vertical;
- y2 -= bottomLeft.vertical;
- }
+ int y = _ty + topLeft.vertical;
+ int y2 = _ty + h - bottomLeft.vertical;
drawBorder(p, _tx, y, _tx + style->borderLeftWidth(), y2, BSLeft, lc, \
style->color(), ls, ignore_top?0:style->borderTopWidth(),
ignore_bottom?0:style->borderBottomWidth());
- if (renderRadii && (!upperLeftBorderStylesMatch || \
!lowerLeftBorderStylesMatch)) {
- if (!upperLeftBorderStylesMatch && topLeft.hasBorderRadius()) {
- int x = _tx + topLeft.horizontal;
- int y = _ty + topLeft.vertical;
- int startAngle = 135;
- int span = 45;
+ if (!upperLeftBorderStylesMatch && topLeft.hasBorderRadius()) {
+ int x = _tx + topLeft.horizontal;
+ int y = _ty + topLeft.vertical;
+ int startAngle = 135;
+ int span = 45;
- // Draw the upper left arc
- drawBorderArc(p, x, y, style->borderLeftWidth(), \
style->borderTopWidth(),
- topLeft, startAngle, span, lc, style->color(), ls);
- }
- if (!lowerLeftBorderStylesMatch && bottomLeft.hasBorderRadius()) {
- int x = _tx + bottomLeft.horizontal;
- int y = _ty + h - bottomLeft.vertical;
- int startAngle = 180;
- int span = 45;
+ // Draw the upper left arc
+ drawBorderArc(p, x, y, style->borderLeftWidth(), \
style->borderTopWidth(), + topLeft, startAngle, span, lc, \
style->color(), ls); + }
+ if (!lowerLeftBorderStylesMatch && bottomLeft.hasBorderRadius()) {
+ int x = _tx + bottomLeft.horizontal;
+ int y = _ty + h - bottomLeft.vertical;
+ int startAngle = 180;
+ int span = 45;
- // Draw the bottom left arc
- drawBorderArc(p, x, y, style->borderLeftWidth(), \
style->borderBottomWidth(),
- bottomLeft, startAngle, span, lc, style->color(), ls);
- }
+ // Draw the bottom left arc
+ drawBorderArc(p, x, y, style->borderLeftWidth(), \
style->borderBottomWidth(), + bottomLeft, startAngle, span, \
lc, style->color(), ls); }
}
if(render_r)
{
- bool ignore_top = (renderRadii && topRight.vertical > 0) ||
+ bool ignore_top = (topRight.vertical > 0) ||
((tc == rc) && (tt == rt) &&
(rs >= DOTTED || rs == INSET) &&
(ts == DOTTED || ts == DASHED || ts == SOLID || ts == OUTSET));
- bool ignore_bottom = (renderRadii && bottomRight.vertical > 0) ||
+ bool ignore_bottom = (bottomRight.vertical > 0) ||
((bc == rc) && (bt == rt) &&
(rs >= DOTTED || rs == INSET) &&
(bs == DOTTED || bs == DASHED || bs == SOLID || bs == INSET));
- int y = _ty;
- int y2 = _ty + h;
- if (renderRadii) {
- y += topRight.vertical;
- y2 -= bottomRight.vertical;
- }
+ int y = _ty + topRight.vertical;
+ int y2 = _ty + h - bottomRight.vertical;
drawBorder(p, _tx + w - style->borderRightWidth(), y, _tx + w, y2, BSRight, \
rc, style->color(), rs, ignore_top?0:style->borderTopWidth(),
ignore_bottom?0:style->borderBottomWidth());
- if (renderRadii && (!upperRightBorderStylesMatch || \
!lowerRightBorderStylesMatch)) {
- if (!upperRightBorderStylesMatch && topRight.hasBorderRadius()) {
- int x = _tx + w - topRight.horizontal;
- int y = _ty + topRight.vertical;
- int startAngle = 0;
- int span = 45;
+ if (!upperRightBorderStylesMatch && topRight.hasBorderRadius()) {
+ int x = _tx + w - topRight.horizontal;
+ int y = _ty + topRight.vertical;
+ int startAngle = 0;
+ int span = 45;
- // Draw the upper right arc
- drawBorderArc(p, x, y, style->borderRightWidth(), \
style->borderTopWidth(),
- topRight, startAngle, span, rc, style->color(), rs);
- }
- if (!lowerRightBorderStylesMatch && bottomRight.hasBorderRadius()) {
- int x = _tx + w - bottomRight.horizontal;
- int y = _ty + h - bottomRight.vertical;
- int startAngle = 315;
- int span = 45;
+ // Draw the upper right arc
+ drawBorderArc(p, x, y, style->borderRightWidth(), \
style->borderTopWidth(), + topRight, startAngle, span, rc, \
style->color(), rs); + }
+ if (!lowerRightBorderStylesMatch && bottomRight.hasBorderRadius()) {
+ int x = _tx + w - bottomRight.horizontal;
+ int y = _ty + h - bottomRight.vertical;
+ int startAngle = 315;
+ int span = 45;
- // Draw the bottom right arc
- drawBorderArc(p, x, y, style->borderRightWidth(), \
style->borderBottomWidth(),
- bottomRight, startAngle, span, rc, style->color(), \
rs);
- }
+ // Draw the bottom right arc
+ drawBorderArc(p, x, y, style->borderRightWidth(), \
style->borderBottomWidth(), + bottomRight, startAngle, span, \
rc, style->color(), rs); }
}
}
--- trunk/KDE/kdelibs/khtml/rendering/render_object.h #892639:892640
@@ -413,6 +413,8 @@
};
virtual void paint( PaintInfo& i, int tx, int ty);
+ void adjustBorderRadii(BorderRadii &tl, BorderRadii &tr, BorderRadii &bl, \
BorderRadii &br, int w, int h) const; +
void drawBorderArc(QPainter *p, int x, int y, float horThickness, float \
vertThickness,
const BorderRadii &radius, int angleStart, int angleSpan, \
const QColor &color,
const QColor &textColor, EBorderStyle style) const;
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic