added some functions with optimized implementation, optimizes most frequent usage
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12113 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -32,6 +32,11 @@
|
|||||||
|
|
||||||
#include "DisplayDriverPainter.h"
|
#include "DisplayDriverPainter.h"
|
||||||
|
|
||||||
|
// TODO: fix invalidation, what about pensize, scale, origin?
|
||||||
|
// Painter calls could return the bounding box arround all
|
||||||
|
// pixels touched by a drawing operation
|
||||||
|
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
DisplayDriverPainter::DisplayDriverPainter()
|
DisplayDriverPainter::DisplayDriverPainter()
|
||||||
: DisplayDriver(),
|
: DisplayDriver(),
|
||||||
@@ -487,7 +492,8 @@ DisplayDriverPainter::StrokeLine(const BPoint &start, const BPoint &end, const R
|
|||||||
if (Lock()) {
|
if (Lock()) {
|
||||||
|
|
||||||
fPainter->SetHighColor(color);
|
fPainter->SetHighColor(color);
|
||||||
fPainter->StrokeLine(start, end);
|
fPainter->SetDrawingMode(B_OP_COPY);
|
||||||
|
fPainter->StrokeLine(start, end, B_SOLID_HIGH);
|
||||||
|
|
||||||
BRect r(start, end);
|
BRect r(start, end);
|
||||||
fGraphicsCard->Invalidate(r);
|
fGraphicsCard->Invalidate(r);
|
||||||
@@ -546,15 +552,19 @@ DisplayDriverPainter::StrokePolygon(BPoint *ptlist, int32 numpts,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// StrokeRect
|
// StrokeRect
|
||||||
|
//
|
||||||
|
// this function is used to draw a one pixel wide rect
|
||||||
void
|
void
|
||||||
DisplayDriverPainter::StrokeRect(const BRect &r, const RGBColor &color)
|
DisplayDriverPainter::StrokeRect(const BRect &r, const RGBColor &color)
|
||||||
{
|
{
|
||||||
if (Lock()) {
|
if (Lock()) {
|
||||||
|
|
||||||
fPainter->SetHighColor(color);
|
fPainter->StrokeRect(r, color.GetColor32());
|
||||||
fPainter->StrokeRect(r);
|
|
||||||
|
|
||||||
fGraphicsCard->Invalidate(r);
|
fGraphicsCard->Invalidate(BRect(r.left, r.top, r.right, r.top));
|
||||||
|
fGraphicsCard->Invalidate(BRect(r.left, r.top + 1, r.left, r.bottom - 1));
|
||||||
|
fGraphicsCard->Invalidate(BRect(r.right, r.top + 1, r.right, r.bottom - 1));
|
||||||
|
fGraphicsCard->Invalidate(BRect(r.left, r.bottom, r.right, r.bottom));
|
||||||
|
|
||||||
Unlock();
|
Unlock();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -289,6 +289,24 @@ Painter::StrokeLine(BPoint a, BPoint b, const pattern& p)
|
|||||||
_Transform(&a);
|
_Transform(&a);
|
||||||
_Transform(&b);
|
_Transform(&b);
|
||||||
|
|
||||||
|
// first, try an optimized version
|
||||||
|
float penSize = _Transform(fPenSize);
|
||||||
|
if (penSize == 1.0 &&
|
||||||
|
(fDrawingMode == B_OP_COPY || fDrawingMode == B_OP_OVER)) {
|
||||||
|
// TODO: fix me
|
||||||
|
// pattern p = *fPatternHandler->GetR5Pattern();
|
||||||
|
if (p == B_SOLID_HIGH &&
|
||||||
|
StraightLine(a, b, fPatternHandler->HighColor().GetColor32())) {
|
||||||
|
SetPenLocation(b);
|
||||||
|
return;
|
||||||
|
} else if (p == B_SOLID_LOW &&
|
||||||
|
StraightLine(a, b, fPatternHandler->LowColor().GetColor32())) {
|
||||||
|
SetPenLocation(b);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
agg::path_storage path;
|
agg::path_storage path;
|
||||||
path.move_to(a.x, a.y);
|
path.move_to(a.x, a.y);
|
||||||
path.line_to(b.x, b.y);
|
path.line_to(b.x, b.y);
|
||||||
@@ -306,6 +324,69 @@ Painter::StrokeLine(BPoint b, const pattern& p)
|
|||||||
StrokeLine(fPenLocation, b);
|
StrokeLine(fPenLocation, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StraightLine
|
||||||
|
bool
|
||||||
|
Painter::StraightLine(BPoint a, BPoint b, const rgb_color& c) const
|
||||||
|
{
|
||||||
|
if (fBuffer) {
|
||||||
|
if (a.x == b.x) {
|
||||||
|
// vertical
|
||||||
|
uint8* dst = fBuffer->row(0);
|
||||||
|
uint32 bpr = fBuffer->stride();
|
||||||
|
int32 x = (int32)a.x;
|
||||||
|
dst += x * 4;
|
||||||
|
int32 y1 = (int32)min_c(a.y, b.y);
|
||||||
|
int32 y2 = (int32)max_c(a.y, b.y);
|
||||||
|
// draw a line, iterate over clipping boxes
|
||||||
|
fBaseRenderer->first_clip_box();
|
||||||
|
do {
|
||||||
|
if (fBaseRenderer->xmin() <= x &&
|
||||||
|
fBaseRenderer->xmax() >= x) {
|
||||||
|
int32 i = max_c(fBaseRenderer->ymin(), y1);
|
||||||
|
int32 end = min_c(fBaseRenderer->ymax(), y2);
|
||||||
|
uint8* handle = dst + i * bpr;
|
||||||
|
for (; i <= end; i++) {
|
||||||
|
handle[0] = c.blue;
|
||||||
|
handle[1] = c.green;
|
||||||
|
handle[2] = c.red;
|
||||||
|
handle += bpr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (fBaseRenderer->next_clip_box());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} else if (a.y == b.y) {
|
||||||
|
// horizontal
|
||||||
|
uint8* dst = fBuffer->row(0);
|
||||||
|
uint32 bpr = fBuffer->stride();
|
||||||
|
int32 y = (int32)a.y;
|
||||||
|
dst += y * bpr;
|
||||||
|
int32 x1 = (int32)min_c(a.x, b.x);
|
||||||
|
int32 x2 = (int32)max_c(a.x, b.x);
|
||||||
|
// draw a line, iterate over clipping boxes
|
||||||
|
fBaseRenderer->first_clip_box();
|
||||||
|
do {
|
||||||
|
if (fBaseRenderer->ymin() <= y &&
|
||||||
|
fBaseRenderer->ymax() >= y) {
|
||||||
|
int32 i = max_c(fBaseRenderer->xmin(), x1);
|
||||||
|
int32 end = min_c(fBaseRenderer->xmax(), x2);
|
||||||
|
uint8* handle = dst + i * 4;
|
||||||
|
for (; i <= end; i++) {
|
||||||
|
handle[0] = c.blue;
|
||||||
|
handle[1] = c.green;
|
||||||
|
handle[2] = c.red;
|
||||||
|
handle += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (fBaseRenderer->next_clip_box());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
// StrokeTriangle
|
// StrokeTriangle
|
||||||
@@ -409,55 +490,123 @@ void
|
|||||||
Painter::StrokeRect(const BRect& r, const pattern& p) const
|
Painter::StrokeRect(const BRect& r, const pattern& p) const
|
||||||
{
|
{
|
||||||
BPoint a(r.left, r.top);
|
BPoint a(r.left, r.top);
|
||||||
BPoint b(r.right, r.top);
|
BPoint b(r.right, r.bottom);
|
||||||
BPoint c(r.right, r.bottom);
|
|
||||||
BPoint d(r.left, r.bottom);
|
|
||||||
_Transform(&a);
|
_Transform(&a);
|
||||||
_Transform(&b);
|
_Transform(&b);
|
||||||
_Transform(&c);
|
|
||||||
_Transform(&d);
|
// first, try an optimized version
|
||||||
|
float penSize = _Transform(fPenSize);
|
||||||
|
if (penSize == 1.0 &&
|
||||||
|
(fDrawingMode == B_OP_COPY || fDrawingMode == B_OP_OVER)) {
|
||||||
|
// TODO: fix me
|
||||||
|
// pattern p = *fPatternHandler->GetR5Pattern();
|
||||||
|
if (p == B_SOLID_HIGH) {
|
||||||
|
StrokeRect(BRect(a, b),
|
||||||
|
fPatternHandler->HighColor().GetColor32());
|
||||||
|
return;
|
||||||
|
} else if (p == B_SOLID_LOW) {
|
||||||
|
StrokeRect(BRect(a, b),
|
||||||
|
fPatternHandler->LowColor().GetColor32());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
agg::path_storage path;
|
agg::path_storage path;
|
||||||
path.move_to(a.x, a.y);
|
path.move_to(a.x, a.y);
|
||||||
|
path.line_to(b.x, a.y);
|
||||||
path.line_to(b.x, b.y);
|
path.line_to(b.x, b.y);
|
||||||
path.line_to(c.x, c.y);
|
path.line_to(a.x, b.y);
|
||||||
path.line_to(d.x, d.y);
|
|
||||||
path.close_polygon();
|
path.close_polygon();
|
||||||
|
|
||||||
_StrokePath(path, p);
|
_StrokePath(path, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StrokeRect
|
||||||
|
void
|
||||||
|
Painter::StrokeRect(const BRect& r, const rgb_color& c) const
|
||||||
|
{
|
||||||
|
StraightLine(BPoint(r.left, r.top),
|
||||||
|
BPoint(r.right - 1, r.top), c);
|
||||||
|
StraightLine(BPoint(r.right, r.top),
|
||||||
|
BPoint(r.right, r.bottom - 1), c);
|
||||||
|
StraightLine(BPoint(r.right, r.bottom),
|
||||||
|
BPoint(r.left + 1, r.bottom), c);
|
||||||
|
StraightLine(BPoint(r.left, r.bottom),
|
||||||
|
BPoint(r.left, r.top + 1), c);
|
||||||
|
}
|
||||||
|
|
||||||
// FillRect
|
// FillRect
|
||||||
void
|
void
|
||||||
Painter::FillRect(const BRect& r, const pattern& p) const
|
Painter::FillRect(const BRect& r, const pattern& p) const
|
||||||
{
|
{
|
||||||
BPoint a(r.left, r.top);
|
BPoint a(r.left, r.top);
|
||||||
BPoint b(r.right, r.top);
|
BPoint b(r.right, r.bottom);
|
||||||
BPoint c(r.right, r.bottom);
|
|
||||||
BPoint d(r.left, r.bottom);
|
|
||||||
_Transform(&a, false);
|
_Transform(&a, false);
|
||||||
_Transform(&b, false);
|
_Transform(&b, false);
|
||||||
_Transform(&c, false);
|
|
||||||
_Transform(&d, false);
|
// first, try an optimized version
|
||||||
|
if (fDrawingMode == B_OP_COPY || fDrawingMode == B_OP_OVER) {
|
||||||
|
// TODO: fix me
|
||||||
|
// pattern p = *fPatternHandler->GetR5Pattern();
|
||||||
|
if (p == B_SOLID_HIGH) {
|
||||||
|
FillRect(BRect(a, b), fPatternHandler->HighColor().GetColor32());
|
||||||
|
return;
|
||||||
|
} else if (p == B_SOLID_LOW) {
|
||||||
|
FillRect(BRect(a, b), fPatternHandler->LowColor().GetColor32());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// account for stricter interpretation of coordinates in AGG
|
// account for stricter interpretation of coordinates in AGG
|
||||||
// the rectangle ranges from the top-left (.0, .0)
|
// the rectangle ranges from the top-left (.0, .0)
|
||||||
// to the bottom-right (.9999, .9999) corner of pixels
|
// to the bottom-right (.9999, .9999) corner of pixels
|
||||||
b.x += 1.0;
|
b.x += 1.0;
|
||||||
c.x += 1.0;
|
b.y += 1.0;
|
||||||
c.y += 1.0;
|
|
||||||
d.y += 1.0;
|
|
||||||
|
|
||||||
agg::path_storage path;
|
agg::path_storage path;
|
||||||
path.move_to(a.x, a.y);
|
path.move_to(a.x, a.y);
|
||||||
|
path.line_to(b.x, a.y);
|
||||||
path.line_to(b.x, b.y);
|
path.line_to(b.x, b.y);
|
||||||
path.line_to(c.x, c.y);
|
path.line_to(a.x, b.y);
|
||||||
path.line_to(d.x, d.y);
|
|
||||||
path.close_polygon();
|
path.close_polygon();
|
||||||
|
|
||||||
_FillPath(path, p);
|
_FillPath(path, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FillRect
|
||||||
|
void
|
||||||
|
Painter::FillRect(const BRect& r, const rgb_color& c) const
|
||||||
|
{
|
||||||
|
if (fBuffer) {
|
||||||
|
uint8* dst = fBuffer->row(0);
|
||||||
|
uint32 bpr = fBuffer->stride();
|
||||||
|
int32 left = (int32)r.left;
|
||||||
|
int32 top = (int32)r.top;
|
||||||
|
int32 right = (int32)r.right;
|
||||||
|
int32 bottom = (int32)r.bottom;
|
||||||
|
// fill rects, iterate over clipping boxes
|
||||||
|
fBaseRenderer->first_clip_box();
|
||||||
|
do {
|
||||||
|
int32 x1 = max_c(fBaseRenderer->xmin(), left);
|
||||||
|
int32 x2 = min_c(fBaseRenderer->xmax(), right);
|
||||||
|
if (x1 <= x2) {
|
||||||
|
int32 y1 = max_c(fBaseRenderer->ymin(), top);
|
||||||
|
int32 y2 = min_c(fBaseRenderer->ymax(), bottom);
|
||||||
|
uint8* offset = dst + x1 * 4;
|
||||||
|
for (; y1 <= y2; y1++) {
|
||||||
|
uint8* handle = offset + y1 * bpr;
|
||||||
|
for (int32 x = x1; x <= x2; x++) {
|
||||||
|
handle[0] = c.blue;
|
||||||
|
handle[1] = c.green;
|
||||||
|
handle[2] = c.red;
|
||||||
|
handle += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (fBaseRenderer->next_clip_box());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// StrokeRoundRect
|
// StrokeRoundRect
|
||||||
void
|
void
|
||||||
Painter::StrokeRoundRect(const BRect& r, float xRadius, float yRadius,
|
Painter::StrokeRoundRect(const BRect& r, float xRadius, float yRadius,
|
||||||
|
|||||||
@@ -382,8 +382,6 @@ ViewHWInterface::SetMode(const display_mode &mode)
|
|||||||
fDisplayMode.virtual_height = mode.virtual_height;
|
fDisplayMode.virtual_height = mode.virtual_height;
|
||||||
fDisplayMode.space = mode.space;
|
fDisplayMode.space = mode.space;
|
||||||
|
|
||||||
printf("ViewHWInterface::SetMode(%s)\n", string_for_color_space((color_space)fDisplayMode.space));
|
|
||||||
|
|
||||||
BRect frame(0.0, 0.0,
|
BRect frame(0.0, 0.0,
|
||||||
fDisplayMode.virtual_width - 1,
|
fDisplayMode.virtual_width - 1,
|
||||||
fDisplayMode.virtual_height - 1);
|
fDisplayMode.virtual_height - 1);
|
||||||
|
|||||||
Reference in New Issue
Block a user