* some cleanup (removed unsued functions, regrouped others)

* FillRect() doesn't use the HW acceleration if the rects
  are too small (< 100 pixel area, about the sweet spot on
  my box) -> the same change should be used for FillRegion as
  well. (4x speed up of rendering large amounts of small rects)
* replaced dynamic allocation and freeing of blit_params and
  fill_rect_params in the accalerant based HWInterfaces on the
  heap with caching to make using the accelerated functions a
  little less expensive
* fixed a bug in bypassing Painter for B_OP_OVER when the
  pattern was B_SOLID_LOW (nothing should be rendered)


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16841 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus 2006-03-19 22:33:00 +00:00
parent af3ac4e80f
commit 8e56a3ff2e
6 changed files with 205 additions and 185 deletions

View File

@ -92,48 +92,40 @@ public:
BRect bounds, const DrawState *d,
bool filled, bool closed);
// this version used by Decorator
// these RGBColor versions are used internally by the server
void StrokePoint(const BPoint& pt,
const RGBColor& color);
void StrokeRect(BRect r, const RGBColor &color);
void FillRect(BRect r, const RGBColor &color);
void FillRegion(BRegion& r, const RGBColor& color);
void StrokeRect(BRect r, const DrawState *d);
void FillRect(BRect r, const DrawState *d);
// for debugging purposes?
// void StrokeRegion(BRegion &r, const DrawState *d);
void FillRegion(BRegion &r, const DrawState *d);
void FillRegion(BRegion &r, const RGBColor& color);
void FillRegion(BRegion& r, const DrawState *d);
void DrawRoundRect(BRect r, float xrad,
float yrad, const DrawState *d,
bool filled);
void DrawShape(const BRect &bounds,
int32 opcount, const uint32 *oplist,
int32 ptcount, const BPoint *ptlist,
const DrawState *d, bool filled);
void DrawShape(const BRect& bounds,
int32 opcount, const uint32* oplist,
int32 ptcount, const BPoint* ptlist,
const DrawState* d, bool filled);
void DrawTriangle(BPoint *pts, const BRect &bounds,
const DrawState *d, bool filled);
void DrawTriangle(BPoint* pts, const BRect& bounds,
const DrawState* d, bool filled);
// this version used by Decorator
void StrokeLine(const BPoint &start,
const BPoint &end, const RGBColor &color);
void StrokeLine(const BPoint& start,
const BPoint& end, const RGBColor& color);
void StrokeLine(const BPoint &start,
const BPoint &end, DrawState *d);
void StrokeLine(const BPoint& start,
const BPoint& end, DrawState* d);
void StrokeLineArray(int32 numlines,
const LineArrayData *data,
const DrawState *d);
// this version used by Decorator
void StrokePoint(const BPoint &pt,
const RGBColor &color);
void StrokePoint(const BPoint &pt,
DrawState *d);
const LineArrayData* data,
const DrawState* d);
// -------- text related calls

View File

@ -58,6 +58,8 @@ operator==(const display_mode& a, const display_mode& b)
return memcmp(&a, &b, sizeof(display_mode)) == 0;
}
const int32 kDefaultParamsCount = 64;
// constructor
AccelerantHWInterface::AccelerantHWInterface()
: HWInterface(),
@ -97,7 +99,12 @@ AccelerantHWInterface::AccelerantHWInterface()
fModeList(NULL),
fBackBuffer(NULL),
fFrontBuffer(new(nothrow) AccelerantBuffer())
fFrontBuffer(new (nothrow) AccelerantBuffer()),
fRectParams(new (nothrow) fill_rect_params[kDefaultParamsCount]),
fRectParamsCount(kDefaultParamsCount),
fBlitParams(new (nothrow) blit_params[kDefaultParamsCount]),
fBlitParamsCount(kDefaultParamsCount)
{
fDisplayMode.virtual_width = 640;
fDisplayMode.virtual_height = 480;
@ -114,6 +121,10 @@ AccelerantHWInterface::~AccelerantHWInterface()
{
delete fBackBuffer;
delete fFrontBuffer;
delete[] fRectParams;
delete[] fBlitParams;
delete[] fModeList;
}
@ -126,6 +137,10 @@ status_t
AccelerantHWInterface::Initialize()
{
status_t ret = HWInterface::Initialize();
if (!fRectParams || !fBlitParams)
return B_NO_MEMORY;
if (ret >= B_OK) {
for (int32 i = 1; fCardFD != B_ENTRY_NOT_FOUND; i++) {
fCardFD = _OpenGraphicsDevice(i);
@ -677,22 +692,33 @@ AccelerantHWInterface::CopyRegion(const clipping_rect* sortedRectList,
if (fAccScreenBlit && fAccAcquireEngine) {
if (fAccAcquireEngine(B_2D_ACCELERATION, 0xff, &fSyncToken, &fEngineToken) >= B_OK) {
// make sure the blit_params cache is large enough
if (fBlitParamsCount < count) {
fBlitParamsCount = (count / kDefaultParamsCount + 1) * kDefaultParamsCount;
// NOTE: realloc() could be used instead...
blit_params* params = new (nothrow) blit_params[fBlitParamsCount];
if (params) {
delete[] fBlitParams;
fBlitParams = params;
} else {
count = fBlitParamsCount;
}
}
// convert the rects
blit_params* params = new blit_params[count];
for (uint32 i = 0; i < count; i++) {
params[i].src_left = (uint16)sortedRectList[i].left;
params[i].src_top = (uint16)sortedRectList[i].top;
fBlitParams[i].src_left = (uint16)sortedRectList[i].left;
fBlitParams[i].src_top = (uint16)sortedRectList[i].top;
params[i].dest_left = (uint16)sortedRectList[i].left + xOffset;
params[i].dest_top = (uint16)sortedRectList[i].top + yOffset;
fBlitParams[i].dest_left = (uint16)sortedRectList[i].left + xOffset;
fBlitParams[i].dest_top = (uint16)sortedRectList[i].top + yOffset;
// NOTE: width and height are expressed as distance, not pixel count!
params[i].width = (uint16)(sortedRectList[i].right - sortedRectList[i].left);
params[i].height = (uint16)(sortedRectList[i].bottom - sortedRectList[i].top);
fBlitParams[i].width = (uint16)(sortedRectList[i].right - sortedRectList[i].left);
fBlitParams[i].height = (uint16)(sortedRectList[i].bottom - sortedRectList[i].top);
}
// go
fAccScreenBlit(fEngineToken, params, count);
fAccScreenBlit(fEngineToken, fBlitParams, count);
// done
if (fAccReleaseEngine)
@ -701,8 +727,6 @@ AccelerantHWInterface::CopyRegion(const clipping_rect* sortedRectList,
// sync
if (fAccSyncToToken)
fAccSyncToToken(&fSyncToken);
delete[] params;
}
}
}
@ -716,11 +740,10 @@ AccelerantHWInterface::FillRegion(/*const*/ BRegion& region, const RGBColor& col
// convert the region
uint32 count;
fill_rect_params* fillParams;
_RegionToRectParams(&region, &fillParams, &count);
_RegionToRectParams(&region, &count);
// go
fAccFillRect(fEngineToken, _NativeColor(color), fillParams, count);
fAccFillRect(fEngineToken, _NativeColor(color), fRectParams, count);
// done
if (fAccReleaseEngine)
@ -729,8 +752,6 @@ AccelerantHWInterface::FillRegion(/*const*/ BRegion& region, const RGBColor& col
// sync
if (fAccSyncToToken)
fAccSyncToToken(&fSyncToken);
delete[] fillParams;
}
}
}
@ -744,11 +765,10 @@ AccelerantHWInterface::InvertRegion(/*const*/ BRegion& region)
// convert the region
uint32 count;
fill_rect_params* fillParams;
_RegionToRectParams(&region, &fillParams, &count);
_RegionToRectParams(&region, &count);
// go
fAccInvertRect(fEngineToken, fillParams, count);
fAccInvertRect(fEngineToken, fRectParams, count);
// done
if (fAccReleaseEngine)
@ -757,8 +777,6 @@ AccelerantHWInterface::InvertRegion(/*const*/ BRegion& region)
// sync
if (fAccSyncToToken)
fAccSyncToToken(&fSyncToken);
delete[] fillParams;
}
}
}
@ -844,18 +862,27 @@ AccelerantHWInterface::_DrawCursor(BRect area) const
// _RegionToRectParams
void
AccelerantHWInterface::_RegionToRectParams(/*const*/ BRegion* region,
fill_rect_params** params,
uint32* count) const
{
*count = region->CountRects();
*params = new fill_rect_params[*count];
if (fRectParamsCount < *count) {
fRectParamsCount = (*count / kDefaultParamsCount + 1) * kDefaultParamsCount;
// NOTE: realloc() could be used instead...
fill_rect_params* params = new (nothrow) fill_rect_params[fRectParamsCount];
if (params) {
delete[] fRectParams;
fRectParams = params;
} else {
*count = fRectParamsCount;
}
}
for (uint32 i = 0; i < *count; i++) {
clipping_rect r = region->RectAtInt(i);
(*params)[i].left = (uint16)r.left;
(*params)[i].top = (uint16)r.top;
(*params)[i].right = (uint16)r.right;
(*params)[i].bottom = (uint16)r.bottom;
fRectParams[i].left = (uint16)r.left;
fRectParams[i].top = (uint16)r.top;
fRectParams[i].right = (uint16)r.right;
fRectParams[i].bottom = (uint16)r.bottom;
}
}

View File

@ -83,7 +83,6 @@ private:
status_t _UpdateModeList();
status_t _UpdateFrameBufferConfig();
void _RegionToRectParams(/*const*/ BRegion* region,
fill_rect_params** params,
uint32* count) const;
uint32 _NativeColor(const RGBColor& color) const;
@ -138,6 +137,11 @@ private:
AccelerantBuffer *fFrontBuffer;
display_mode fDisplayMode;
mutable fill_rect_params* fRectParams;
mutable uint32 fRectParamsCount;
mutable blit_params* fBlitParams;
mutable uint32 fBlitParamsCount;
};
#endif // ACCELERANT_HW_INTERFACE_H

View File

@ -283,6 +283,8 @@ DWindow::FrameMoved(BPoint newOffset)
// #pragma mark -
const int32 kDefaultParamsCount = 64;
DWindowHWInterface::DWindowHWInterface()
: HWInterface(),
fFrontBuffer(new DWindowBuffer()),
@ -316,7 +318,12 @@ DWindowHWInterface::DWindowHWInterface()
fAccScreenBlit(NULL),
fAccSetCursorShape(NULL),
fAccMoveCursor(NULL),
fAccShowCursor(NULL)
fAccShowCursor(NULL),
fRectParams(new (nothrow) fill_rect_params[kDefaultParamsCount]),
fRectParamsCount(kDefaultParamsCount),
fBlitParams(new (nothrow) blit_params[kDefaultParamsCount]),
fBlitParamsCount(kDefaultParamsCount)
{
fDisplayMode.virtual_width = 800;
fDisplayMode.virtual_height = 600;
@ -333,6 +340,9 @@ DWindowHWInterface::~DWindowHWInterface()
fWindow->Quit();
}
delete[] fRectParams;
delete[] fBlitParams;
delete fFrontBuffer;
be_app->Lock();
@ -345,6 +355,10 @@ status_t
DWindowHWInterface::Initialize()
{
status_t ret = HWInterface::Initialize();
if (!fRectParams || !fBlitParams)
return B_NO_MEMORY;
if (ret >= B_OK) {
for (int32 i = 1; fCardFD != B_ENTRY_NOT_FOUND; i++) {
fCardFD = _OpenGraphicsDevice(i);
@ -889,22 +903,33 @@ DWindowHWInterface::CopyRegion(const clipping_rect* sortedRectList,
if (fAccScreenBlit && fAccAcquireEngine) {
if (fAccAcquireEngine(B_2D_ACCELERATION, 0xff, &fSyncToken, &fEngineToken) >= B_OK) {
// make sure the blit_params cache is large enough
if (fBlitParamsCount < count) {
fBlitParamsCount = (count / kDefaultParamsCount + 1) * kDefaultParamsCount;
// NOTE: realloc() could be used instead...
blit_params* params = new (nothrow) blit_params[fBlitParamsCount];
if (params) {
delete[] fBlitParams;
fBlitParams = params;
} else {
count = fBlitParamsCount;
}
}
// convert the rects
blit_params* params = new blit_params[count];
for (uint32 i = 0; i < count; i++) {
params[i].src_left = (uint16)sortedRectList[i].left + fXOffset;
params[i].src_top = (uint16)sortedRectList[i].top + fYOffset;
fBlitParams[i].src_left = (uint16)sortedRectList[i].left + fXOffset;
fBlitParams[i].src_top = (uint16)sortedRectList[i].top + fYOffset;
params[i].dest_left = (uint16)sortedRectList[i].left + xOffset + fXOffset;
params[i].dest_top = (uint16)sortedRectList[i].top + yOffset + fYOffset;
fBlitParams[i].dest_left = (uint16)sortedRectList[i].left + xOffset + fXOffset;
fBlitParams[i].dest_top = (uint16)sortedRectList[i].top + yOffset + fYOffset;
// NOTE: width and height are expressed as distance, not pixel count!
params[i].width = (uint16)(sortedRectList[i].right - sortedRectList[i].left);
params[i].height = (uint16)(sortedRectList[i].bottom - sortedRectList[i].top);
fBlitParams[i].width = (uint16)(sortedRectList[i].right - sortedRectList[i].left);
fBlitParams[i].height = (uint16)(sortedRectList[i].bottom - sortedRectList[i].top);
}
// go
fAccScreenBlit(fEngineToken, params, count);
fAccScreenBlit(fEngineToken, fBlitParams, count);
// done
if (fAccReleaseEngine)
@ -913,8 +938,6 @@ DWindowHWInterface::CopyRegion(const clipping_rect* sortedRectList,
// sync
if (fAccSyncToToken)
fAccSyncToToken(&fSyncToken);
delete[] params;
}
}
}
@ -928,11 +951,10 @@ DWindowHWInterface::FillRegion(/*const*/ BRegion& region, const RGBColor& color)
// convert the region
uint32 count;
fill_rect_params* fillParams;
_RegionToRectParams(&region, &fillParams, &count);
_RegionToRectParams(&region, &count);
// go
fAccFillRect(fEngineToken, _NativeColor(color), fillParams, count);
fAccFillRect(fEngineToken, _NativeColor(color), fRectParams, count);
// done
if (fAccReleaseEngine)
@ -941,8 +963,6 @@ DWindowHWInterface::FillRegion(/*const*/ BRegion& region, const RGBColor& color)
// sync
if (fAccSyncToToken)
fAccSyncToToken(&fSyncToken);
delete[] fillParams;
}
}
}
@ -956,11 +976,10 @@ DWindowHWInterface::InvertRegion(/*const*/ BRegion& region)
// convert the region
uint32 count;
fill_rect_params* fillParams;
_RegionToRectParams(&region, &fillParams, &count);
_RegionToRectParams(&region, &count);
// go
fAccInvertRect(fEngineToken, fillParams, count);
fAccInvertRect(fEngineToken, fRectParams, count);
// done
if (fAccReleaseEngine)
@ -970,7 +989,6 @@ DWindowHWInterface::InvertRegion(/*const*/ BRegion& region)
if (fAccSyncToToken)
fAccSyncToToken(&fSyncToken);
delete[] fillParams;
} else {
fprintf(stderr, "AcquireEngine failed!\n");
}
@ -1027,18 +1045,27 @@ DWindowHWInterface::SetOffset(int32 left, int32 top)
// _RegionToRectParams
void
DWindowHWInterface::_RegionToRectParams(/*const*/ BRegion* region,
fill_rect_params** params,
uint32* count) const
{
*count = region->CountRects();
*params = new fill_rect_params[*count];
if (fRectParamsCount < *count) {
fRectParamsCount = (*count / kDefaultParamsCount + 1) * kDefaultParamsCount;
// NOTE: realloc() could be used instead...
fill_rect_params* params = new (nothrow) fill_rect_params[fRectParamsCount];
if (params) {
delete[] fRectParams;
fRectParams = params;
} else {
*count = fRectParamsCount;
}
}
for (uint32 i = 0; i < *count; i++) {
clipping_rect r = region->RectAtInt(i);
(*params)[i].left = (uint16)(r.left + fXOffset);
(*params)[i].top = (uint16)(r.top + fYOffset);
(*params)[i].right = (uint16)(r.right + fXOffset);
(*params)[i].bottom = (uint16)(r.bottom + fYOffset);
fRectParams[i].left = (uint16)r.left + fXOffset;
fRectParams[i].top = (uint16)r.top + fYOffset;
fRectParams[i].right = (uint16)r.right + fXOffset;
fRectParams[i].bottom = (uint16)r.bottom + fYOffset;
}
}

View File

@ -88,7 +88,6 @@ class DWindowHWInterface : public HWInterface {
status_t _UpdateFrameBufferConfig();
void _RegionToRectParams(/*const*/ BRegion* region,
fill_rect_params** params,
uint32* count) const;
uint32 _NativeColor(const RGBColor& color) const;
@ -124,6 +123,11 @@ class DWindowHWInterface : public HWInterface {
frame_buffer_config fFrameBufferConfig;
BString fCardNameInDevFS;
mutable fill_rect_params* fRectParams;
mutable uint32 fRectParamsCount;
mutable blit_params* fBlitParams;
mutable uint32 fBlitParamsCount;
};
#endif // D_WINDOW_HW_INTERACE_H

View File

@ -549,8 +549,15 @@ DrawingEngine::DrawPolygon(BPoint* ptlist, int32 numpts,
}
}
// StrokeRect
//
// #pragma mark - RGBColor
void
DrawingEngine::StrokePoint(const BPoint& pt, const RGBColor &color)
{
StrokeLine(pt, pt, color);
}
// this function is used to draw a one pixel wide rect
void
DrawingEngine::StrokeRect(BRect r, const RGBColor &color)
@ -578,7 +585,7 @@ DrawingEngine::StrokeRect(BRect r, const RGBColor &color)
}
}
// FillRect
void
DrawingEngine::FillRect(BRect r, const RGBColor& color)
{
@ -609,7 +616,42 @@ DrawingEngine::FillRect(BRect r, const RGBColor& color)
}
}
// StrokeRect
void
DrawingEngine::FillRegion(BRegion& r, const RGBColor& color)
{
// NOTE: Write locking because we might use HW acceleration.
// This needs to be investigated, I'm doing this because of
// gut feeling.
// NOTE: region expected to be already clipped correctly!!
if (WriteLock()) {
fGraphicsCard->HideSoftwareCursor(r.Frame());
bool doInSoftware = true;
// try hardware optimized version first
if ((fAvailableHWAccleration & HW_ACC_FILL_REGION) != 0) {
fGraphicsCard->FillRegion(r, color);
doInSoftware = false;
}
if (doInSoftware) {
int32 count = r.CountRects();
for (int32 i = 0; i < count; i++) {
fPainter->FillRectNoClipping(r.RectAt(i), color.GetColor32());
}
fGraphicsCard->Invalidate(r.Frame());
}
fGraphicsCard->ShowSoftwareCursor();
WriteUnlock();
}
}
// #pragma mark - DrawState
void
DrawingEngine::StrokeRect(BRect r, const DrawState *d)
{
@ -634,7 +676,7 @@ DrawingEngine::StrokeRect(BRect r, const DrawState *d)
}
}
// FillRect
void
DrawingEngine::FillRect(BRect r, const DrawState *d)
{
@ -648,20 +690,24 @@ DrawingEngine::FillRect(BRect r, const DrawState *d)
fGraphicsCard->HideSoftwareCursor(r);
bool doInSoftware = true;
// try hardware optimized version first
if ((fAvailableHWAccleration & HW_ACC_FILL_REGION) != 0
&& (d->GetDrawingMode() == B_OP_COPY
|| d->GetDrawingMode() == B_OP_OVER)) {
if (d->GetPattern() == B_SOLID_HIGH) {
BRegion region(r);
region.IntersectWith(fPainter->ClippingRegion());
fGraphicsCard->FillRegion(region, d->HighColor());
doInSoftware = false;
} else if (d->GetPattern() == B_SOLID_LOW) {
BRegion region(r);
region.IntersectWith(fPainter->ClippingRegion());
fGraphicsCard->FillRegion(region, d->LowColor());
doInSoftware = false;
if ((r.Width() + 1) * (r.Height() + 1) > 100.0) {
// try hardware optimized version first
// if the rect is large enough
if ((fAvailableHWAccleration & HW_ACC_FILL_REGION) != 0) {
if (d->GetPattern() == B_SOLID_HIGH
&& (d->GetDrawingMode() == B_OP_COPY
|| d->GetDrawingMode() == B_OP_OVER)) {
BRegion region(r);
region.IntersectWith(fPainter->ClippingRegion());
fGraphicsCard->FillRegion(region, d->HighColor());
doInSoftware = false;
} else if (d->GetPattern() == B_SOLID_LOW
&& d->GetDrawingMode() == B_OP_COPY) {
BRegion region(r);
region.IntersectWith(fPainter->ClippingRegion());
fGraphicsCard->FillRegion(region, d->LowColor());
doInSoftware = false;
}
}
}
if (doInSoftware) {
@ -677,36 +723,8 @@ DrawingEngine::FillRect(BRect r, const DrawState *d)
WriteUnlock();
}
}
/*
// StrokeRegion
void
DrawingEngine::StrokeRegion(BRegion& r, const DrawState *d)
{
if (Lock()) {
BRect clipped(r.Frame());
extend_by_stroke_width(clipped, d);
clipped = fPainter->ClipRect(clipped);
if (clipped.IsValid()) {
fGraphicsCard->HideSoftwareCursor(clipped);
fPainter->SetDrawState(d);
BRect touched = fPainter->StrokeRect(r.RectAt(0));
int32 count = r.CountRects();
for (int32 i = 1; i < count; i++) {
touched = touched | fPainter->StrokeRect(r.RectAt(i));
}
fGraphicsCard->Invalidate(touched);
fGraphicsCard->ShowSoftwareCursor();
}
Unlock();
}
}
*/
// FillRegion
void
DrawingEngine::FillRegion(BRegion& r, const DrawState *d)
{
@ -720,14 +738,15 @@ DrawingEngine::FillRegion(BRegion& r, const DrawState *d)
bool doInSoftware = true;
// try hardware optimized version first
if ((fAvailableHWAccleration & HW_ACC_FILL_REGION) != 0
&& (d->GetDrawingMode() == B_OP_COPY
|| d->GetDrawingMode() == B_OP_OVER)) {
if (d->GetPattern() == B_SOLID_HIGH) {
if ((fAvailableHWAccleration & HW_ACC_FILL_REGION) != 0) {
if (d->GetPattern() == B_SOLID_HIGH
&& (d->GetDrawingMode() == B_OP_COPY
|| d->GetDrawingMode() == B_OP_OVER)) {
r.IntersectWith(fPainter->ClippingRegion());
fGraphicsCard->FillRegion(r, d->HighColor());
doInSoftware = false;
} else if (d->GetPattern() == B_SOLID_LOW) {
} else if (d->GetPattern() == B_SOLID_LOW
&& d->GetDrawingMode() == B_OP_COPY) {
r.IntersectWith(fPainter->ClippingRegion());
fGraphicsCard->FillRegion(r, d->LowColor());
doInSoftware = false;
@ -755,42 +774,6 @@ DrawingEngine::FillRegion(BRegion& r, const DrawState *d)
}
// FillRegion
void
DrawingEngine::FillRegion(BRegion& r, const RGBColor& color)
{
// NOTE: Write locking because we might use HW acceleration.
// This needs to be investigated, I'm doing this because of
// gut feeling.
// NOTE: region expected to be already clipped correctly!!
if (WriteLock()) {
fGraphicsCard->HideSoftwareCursor(r.Frame());
bool doInSoftware = true;
// try hardware optimized version first
if ((fAvailableHWAccleration & HW_ACC_FILL_REGION) != 0) {
fGraphicsCard->FillRegion(r, color);
doInSoftware = false;
}
if (doInSoftware) {
int32 count = r.CountRects();
for (int32 i = 0; i < count; i++) {
fPainter->FillRectNoClipping(r.RectAt(i), color.GetColor32());
}
BRect touched = r.Frame();
fGraphicsCard->Invalidate(touched);
}
fGraphicsCard->ShowSoftwareCursor();
WriteUnlock();
}
}
void
DrawingEngine::DrawRoundRect(BRect r, float xrad, float yrad,
const DrawState* d, bool filled)
@ -970,25 +953,8 @@ DrawingEngine::StrokeLineArray(int32 numLines,
}
}
// StrokePoint
//
// * this function is only used by Decorators
void
DrawingEngine::StrokePoint(const BPoint& pt, const RGBColor &color)
{
StrokeLine(pt, pt, color);
}
// StrokePoint
void
DrawingEngine::StrokePoint(const BPoint& pt, DrawState *context)
{
StrokeLine(pt, pt, context);
}
// #pragma mark -
// DrawString
BPoint
DrawingEngine::DrawString(const char* string, int32 length,
const BPoint& pt, DrawState* d,