From 9512339a6f3f027d9947d617ff73c8efaa5f9b78 Mon Sep 17 00:00:00 2001 From: shadow303 Date: Wed, 12 Feb 2003 23:21:12 +0000 Subject: [PATCH] Implement FillPolygon. Remove some old junk. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@2697 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/servers/app/server/AccelerantDriver.cpp | 252 ++++++++++++++++++-- src/servers/app/server/AccelerantDriver.h | 5 +- 2 files changed, 236 insertions(+), 21 deletions(-) diff --git a/src/servers/app/server/AccelerantDriver.cpp b/src/servers/app/server/AccelerantDriver.cpp index 00bd907f46..a29e5a0859 100644 --- a/src/servers/app/server/AccelerantDriver.cpp +++ b/src/servers/app/server/AccelerantDriver.cpp @@ -45,18 +45,15 @@ #define CHECK_X(a) ( (a >= 0) || (a <= mDisplayMode.virtual_width-1) ) #define CHECK_Y(a) ( (a >= 0) || (a <= mDisplayMode.virtual_height-1) ) -/* Stuff to investigate: - Effect of pensize on fill operations - Pattern details - start point, rectangles drawn counter-clockwise? - Maybe the pattern is always relative to (0,0) - Do I need to deal with things that may be clipped entirely? -*/ -/* Need to check which functions should move the pen position */ +/* TODO: Need to check which functions should move the pen position */ +/* TODO: Add handling of draw modes */ class AccLineCalc { public: + AccLineCalc(); AccLineCalc(const BPoint &pta, const BPoint &ptb); + void SetPoints(const BPoint &pta, const BPoint &ptb); float GetX(float y); float GetY(float x); float Slope(void) { return slope; } @@ -65,6 +62,7 @@ public: float MinY(); float MaxX(); float MaxY(); + void Swap(AccLineCalc &from); private: float slope; float offset; @@ -75,6 +73,10 @@ private: float maxy; }; +AccLineCalc::AccLineCalc() +{ +} + AccLineCalc::AccLineCalc(const BPoint &pta, const BPoint &ptb) { start=pta; @@ -87,6 +89,27 @@ AccLineCalc::AccLineCalc(const BPoint &pta, const BPoint &ptb) maxy = MAX(start.y,end.y); } +void AccLineCalc::SetPoints(const BPoint &pta, const BPoint &ptb) +{ + start=pta; + end=ptb; + slope=(start.y-end.y)/(start.x-end.x); + offset=start.y-(slope * start.x); + minx = MIN(start.x,end.x); + maxx = MAX(start.x,end.x); + miny = MIN(start.y,end.y); + maxy = MAX(start.y,end.y); +} + +void AccLineCalc::Swap(AccLineCalc &from) +{ + BPoint pta, ptb; + pta = start; + ptb = end; + SetPoints(from.start,from.end); + from.SetPoints(pta,ptb); +} + float AccLineCalc::GetX(float y) { return ( (y-offset)/slope ); @@ -308,9 +331,8 @@ void AccelerantDriver::DrawBitmap(ServerBitmap *bmp, BRect src, BRect dest, Laye \param d Data structure containing any other data necessary for the call. Always non-NULL. \param delta Extra character padding */ -void AccelerantDriver::DrawString(const char *string, int32 length, BPoint pt, LayerData *d, escapement_delta *delta=NULL) +void AccelerantDriver::DrawString(const char *string, int32 length, BPoint pt, LayerData *d, escapement_delta *edelta=NULL) { -#if 0 if(!string || !d || !d->font) return; @@ -436,12 +458,15 @@ void AccelerantDriver::DrawString(const char *string, int32 length, BPoint pt, L if(!error) { + //TODO: Replace BlitGray2RGB32 and BlitMono2RGB32 + /* if(antialias) BlitGray2RGB32(&slot->bitmap, BPoint(slot->bitmap_left,pt.y-(slot->bitmap_top-pt.y)), d); else BlitMono2RGB32(&slot->bitmap, BPoint(slot->bitmap_left,pt.y-(slot->bitmap_top-pt.y)), d); + */ } else printf("Couldn't load character %c\n", string[i]); @@ -453,7 +478,6 @@ void AccelerantDriver::DrawString(const char *string, int32 length, BPoint pt, L } FT_Done_Face(face); _Unlock(); -#endif } /*! @@ -821,9 +845,114 @@ void AccelerantDriver::FillPolygon(BPoint *ptlist, int32 numpts, BRect rect, Lay all pairs of intersections. Watch out for horizontal line segments. */ _Lock(); + if ( !ptlist || (numpts < 3) || (sizeof(ptlist) < numpts*sizeof(BPoint)) ) + { + _Unlock(); + return; + } PatternHandler pattern(pat); pattern.SetColors(d->highcolor, d->lowcolor); + BPoint *currentPoint, *nextPoint; + BPoint tempNextPoint; + BPoint tempCurrentPoint; + int currentIndex, bestIndex, i, j, y; + AccLineCalc *segmentArray = new AccLineCalc[2*numpts]; + int numSegments = 0; + + /* Generate the segment list */ + currentPoint = ptlist; + currentIndex = 0; + nextPoint = &ptlist[1]; + while (currentPoint) + { + for (i=0; i currentPoint->y) && (ptlist[i].y < nextPoint->y)) || + ((ptlist[i].y < currentPoint->y) && (ptlist[i].y > nextPoint->y)) ) + { + tempNextPoint.x = ptlist[i].x; + tempNextPoint.y = ptlist[i].y; + nextPoint = &tempNextPoint; + } + } + if ( numSegments >= 2*numpts ) + { + printf("ERROR: Insufficient memory allocated to segment array\n"); + return; + } + segmentArray[numSegments].SetPoints(*currentPoint,*nextPoint); + numSegments++; + if ( nextPoint == &tempNextPoint ) + { + tempCurrentPoint = tempNextPoint; + currentPoint = &tempCurrentPoint; + nextPoint = &ptlist[(currentIndex+1)%numpts]; + } + else if ( nextPoint == ptlist ) + { + currentPoint = NULL; + } + else + { + currentPoint = nextPoint; + currentIndex++; + nextPoint = &ptlist[(currentIndex+1)%numpts]; + } + } + + /* Selection sort the segments. Probably should replace this later. */ + for (i=0; i y) + break; + if (segmentArray[i].MaxY() < y) + { + i++; + continue; + } + if (segmentArray[i].MinY() == segmentArray[i].MaxY()) + { + if ( (segmentArray[i].MinX() < mDisplayMode.virtual_width) && + (segmentArray[i].MaxX() >= 0) ) + HLine(CLIP_X(ROUND(segmentArray[i].MinX())), + CLIP_X(ROUND(segmentArray[i].MaxX())), + y, &pattern); + i++; + } + else + { + if ( (segmentArray[i].GetX(y) < mDisplayMode.virtual_width) && + (segmentArray[i+1].GetX(y) >= 0) ) + HLine(CLIP_X(ROUND(segmentArray[i].GetX(y))), + CLIP_X(ROUND(segmentArray[i+1].GetX(y))), + y, &pattern); + i+=2; + } + } + } + } + _Unlock(); } @@ -1137,24 +1266,67 @@ void AccelerantDriver::InvertRect(BRect r) index[j]^=0xFFFFFF00L; index = (uint32 *)((uint8 *)index+mFrameBufferConfig.bytes_per_row); } - break; } + break; case B_RGB16_BIG: case B_RGB16_LITTLE: - // TODO: Implement - printf("ScreenDriver::16-bit mode unimplemented\n"); + { + uint16 width=r.IntegerWidth(); + uint16 height=r.IntegerHeight(); + uint16 *start=(uint16*)mFrameBufferConfig.frame_buffer; + uint16 *index; + start = (uint16 *)((uint8 *)start+(int32)r.top*mFrameBufferConfig.bytes_per_row); + start+=(int32)r.left; + + index = start; + for(int32 i=0;i