* fix some issues with line placement, now it should be as close to R5
as possible without unacceptable overhead. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21676 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -289,8 +289,9 @@ Painter::StrokeLine(BPoint a, BPoint b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// first, try an optimized version
|
// first, try an optimized version
|
||||||
if (fPenSize == 1.0 &&
|
if (fPenSize == 1.0
|
||||||
(fDrawingMode == B_OP_COPY || fDrawingMode == B_OP_OVER)) {
|
&& (fDrawingMode == B_OP_COPY || fDrawingMode == B_OP_OVER)) {
|
||||||
|
|
||||||
pattern pat = *fPatternHandler.GetR5Pattern();
|
pattern pat = *fPatternHandler.GetR5Pattern();
|
||||||
if (pat == B_SOLID_HIGH &&
|
if (pat == B_SOLID_HIGH &&
|
||||||
StraightLine(a, b, fPatternHandler.HighColor().GetColor32())) {
|
StraightLine(a, b, fPatternHandler.HighColor().GetColor32())) {
|
||||||
@@ -305,19 +306,59 @@ Painter::StrokeLine(BPoint a, BPoint b)
|
|||||||
|
|
||||||
if (a == b) {
|
if (a == b) {
|
||||||
// special case dots
|
// special case dots
|
||||||
fPath.move_to(a.x, a.y);
|
if (fPenSize == 1.0 && !fSubpixelPrecise) {
|
||||||
fPath.line_to(a.x + 1, a.y);
|
if (fClippingRegion->Contains(a)) {
|
||||||
fPath.line_to(a.x + 1, a.y + 1);
|
agg::rgba8 dummyColor;
|
||||||
fPath.line_to(a.x, a.y + 1);
|
fPixelFormat.blend_pixel(a.x, a.y, dummyColor, 255);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fPath.move_to(a.x, a.y);
|
||||||
|
fPath.line_to(a.x + 1, a.y);
|
||||||
|
fPath.line_to(a.x + 1, a.y + 1);
|
||||||
|
fPath.line_to(a.x, a.y + 1);
|
||||||
|
|
||||||
touched = _FillPath(fPath);
|
touched = _FillPath(fPath);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// do the pixel center offset here
|
// do the pixel center offset here
|
||||||
if (!fSubpixelPrecise && fmodf(fPenSize, 2.0) != 0.0) {
|
// tweak ends to "include" the pixel at the index,
|
||||||
a.x += 0.5;
|
// we need to do this in order to produce results like R5,
|
||||||
a.y += 0.5;
|
// where coordinates were inclusive
|
||||||
b.x += 0.5;
|
if (!fSubpixelPrecise) {
|
||||||
b.y += 0.5;
|
bool centerOnLine = fmodf(fPenSize, 2.0) != 0.0;
|
||||||
|
if (a.x == b.x) {
|
||||||
|
// shift to pixel center vertically
|
||||||
|
if (centerOnLine) {
|
||||||
|
a.x += 0.5;
|
||||||
|
b.x += 0.5;
|
||||||
|
}
|
||||||
|
// extend on bottom end
|
||||||
|
if (a.y < b.y)
|
||||||
|
b.y++;
|
||||||
|
else
|
||||||
|
a.y++;
|
||||||
|
} else if (a.y == b.y) {
|
||||||
|
if (centerOnLine) {
|
||||||
|
// shift to pixel center horizontally
|
||||||
|
a.y += 0.5;
|
||||||
|
b.y += 0.5;
|
||||||
|
}
|
||||||
|
// extend on right end
|
||||||
|
if (a.x < b.x)
|
||||||
|
b.x++;
|
||||||
|
else
|
||||||
|
a.x++;
|
||||||
|
} else {
|
||||||
|
// do this regardless of pensize
|
||||||
|
if (a.x < b.x)
|
||||||
|
b.x++;
|
||||||
|
else
|
||||||
|
a.x++;
|
||||||
|
if (a.y < b.y)
|
||||||
|
b.y++;
|
||||||
|
else
|
||||||
|
a.y++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fPath.move_to(a.x, a.y);
|
fPath.move_to(a.x, a.y);
|
||||||
@@ -1053,14 +1094,14 @@ Painter::InvertRect(const BRect& r) const
|
|||||||
// #pragma mark - private
|
// #pragma mark - private
|
||||||
|
|
||||||
// _Transform
|
// _Transform
|
||||||
void
|
inline void
|
||||||
Painter::_Transform(BPoint* point, bool centerOffset) const
|
Painter::_Transform(BPoint* point, bool centerOffset) const
|
||||||
{
|
{
|
||||||
// rounding
|
// rounding
|
||||||
if (!fSubpixelPrecise) {
|
if (!fSubpixelPrecise) {
|
||||||
// TODO: validate usage of floor() for values < 0
|
// TODO: validate usage of floor() for values < 0
|
||||||
point->x = floorf(point->x);
|
point->x = (int32)point->x;
|
||||||
point->y = floorf(point->y);
|
point->y = (int32)point->y;
|
||||||
}
|
}
|
||||||
// this code is supposed to move coordinates to the center of pixels,
|
// this code is supposed to move coordinates to the center of pixels,
|
||||||
// as AGG considers (0,0) to be the "upper left corner" of a pixel,
|
// as AGG considers (0,0) to be the "upper left corner" of a pixel,
|
||||||
@@ -1072,7 +1113,7 @@ Painter::_Transform(BPoint* point, bool centerOffset) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// _Transform
|
// _Transform
|
||||||
BPoint
|
inline BPoint
|
||||||
Painter::_Transform(const BPoint& point, bool centerOffset) const
|
Painter::_Transform(const BPoint& point, bool centerOffset) const
|
||||||
{
|
{
|
||||||
BPoint ret = point;
|
BPoint ret = point;
|
||||||
@@ -1579,14 +1620,7 @@ Painter::_StrokePath(VertexSource& path) const
|
|||||||
agg::conv_stroke<VertexSource> stroke(path);
|
agg::conv_stroke<VertexSource> stroke(path);
|
||||||
stroke.width(fPenSize);
|
stroke.width(fPenSize);
|
||||||
|
|
||||||
// special case line width = 1 with square caps
|
stroke.line_cap(agg_line_cap_mode_for(fLineCapMode));
|
||||||
// this has a couple of advantages and it looks
|
|
||||||
// like this is also the R5 behaviour.
|
|
||||||
if (fPenSize == 1.0 && fLineCapMode == B_BUTT_CAP) {
|
|
||||||
stroke.line_cap(agg::square_cap);
|
|
||||||
} else {
|
|
||||||
stroke.line_cap(agg_line_cap_mode_for(fLineCapMode));
|
|
||||||
}
|
|
||||||
stroke.line_join(agg_line_join_mode_for(fLineJoinMode));
|
stroke.line_join(agg_line_join_mode_for(fLineJoinMode));
|
||||||
stroke.miter_limit(fMiterLimit);
|
stroke.miter_limit(fMiterLimit);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user