@@ -247,8 +247,6 @@ void GraphicsDriver::DrawRectangleNative(
247247
248248 int stride = GetWidthInWords (bitmap.width ) * 2 ;
249249
250- const CLR_UINT16 opacity = brush.opacity ;
251-
252250 int xSrc = 0 , ySrc = 0 ;
253251 // If the outset rect is completely outside of the drawing region, we can safely return (inset rect is always inside
254252 // the outset rect)
@@ -290,6 +288,37 @@ void GraphicsDriver::DrawRectangleNative(
290288 }
291289 }
292290
291+ // Fill
292+ if (brush.opacity != PAL_GFX_Bitmap::c_OpacityTransparent)
293+ {
294+ GFX_Rect insetRect;
295+
296+ insetRect.left = insetX;
297+ insetRect.top = insetY;
298+ insetRect.right = insetX + insetWidth - 1 ;
299+ insetRect.bottom = insetY + insetHeight - 1 ;
300+
301+ GraphicsDriver::FillRectangleNative (bitmap, brush, insetRect);
302+ }
303+ }
304+
305+ void GraphicsDriver::FillRectangleNative (const PAL_GFX_Bitmap &bitmap, GFX_Brush &brush, const GFX_Rect &rectangle)
306+ {
307+ int x = rectangle.left ;
308+ int y = rectangle.top ;
309+ int width = rectangle.Width ();
310+ int height = rectangle.Height ();
311+
312+ int xSrc = 0 , ySrc = 0 ;
313+ if (ClipToVisible (bitmap, x, y, width, height, NULL , xSrc, ySrc) == false )
314+ {
315+ return ;
316+ }
317+
318+ int stride = GetWidthInWords (bitmap.width ) * 2 ;
319+
320+ const CLR_UINT16 opacity = brush.opacity ;
321+
293322 // Fills (Gradient / Translucent / Solid)
294323 if (opacity != 0 )
295324 {
@@ -301,9 +330,9 @@ void GraphicsDriver::DrawRectangleNative(
301330 // Solid fill (including Translucent fill)
302331 CLR_UINT32 fillColor = brush.gradientStartColor ;
303332
304- if (insetWidth > 0 && insetHeight > 0 )
333+ if (width > 0 && height > 0 )
305334 {
306- CLR_UINT16 *curRow = ((CLR_UINT16 *)bitmap.data ) + insetY * stride + insetX ;
335+ CLR_UINT16 *curRow = ((CLR_UINT16 *)bitmap.data ) + y * stride + x ;
307336 CLR_UINT16 *curPixel = curRow;
308337
309338 if (opacity == PAL_GFX_Bitmap::c_OpacityOpaque)
@@ -313,33 +342,36 @@ void GraphicsDriver::DrawRectangleNative(
313342 CLR_UINT16 *startRow = curRow;
314343
315344 // Draw the first row
316- for (int col = 0 ; col < insetWidth ; col++, curPixel++)
345+ for (int col = 0 ; col < width ; col++, curPixel++)
317346 {
318347 *curPixel = fillColor;
319348 }
320349
321350 // Just memcpy the first row to all subsequent rows, which is moderately faster
322- for (int row = 1 ; row < insetHeight ; row++)
351+ for (int row = 1 ; row < height ; row++)
323352 {
324353 curRow += stride;
325354
326- memcpy (curRow, startRow, insetWidth * 2 );
355+ memcpy (curRow, startRow, width * 2 );
327356 }
328357 }
329358 else
330359 {
331360 CLR_UINT16 lastPixel = *curPixel;
332361 CLR_UINT16 interpolated = g_GraphicsDriver.NativeColorInterpolate (fillColor, lastPixel, opacity);
333- for (int row = 0 ; row < insetHeight; row++, curRow += stride)
362+
363+ for (int row = 0 ; row < height; row++, curRow += stride)
334364 {
335365 curPixel = curRow;
336- for (int col = 0 ; col < insetWidth; col++, curPixel++)
366+
367+ for (int col = 0 ; col < width; col++, curPixel++)
337368 {
338369 if (*curPixel != lastPixel)
339370 {
340371 lastPixel = *curPixel;
341372 interpolated = g_GraphicsDriver.NativeColorInterpolate (fillColor, lastPixel, opacity);
342373 }
374+
343375 *curPixel = interpolated;
344376 }
345377 }
@@ -375,7 +407,7 @@ void GraphicsDriver::DrawRectangleNative(
375407
376408 const int LIMIT = 1 << 12 ;
377409
378- CLR_UINT16 *curRow = ((CLR_UINT16 *)bitmap.data ) + insetY * stride + insetX ;
410+ CLR_UINT16 *curRow = ((CLR_UINT16 *)bitmap.data ) + y * stride + x ;
379411
380412 CLR_UINT32 scalar = (gradientDeltaY * gradientDeltaY * LIMIT) /
381413 (gradientDeltaY * gradientDeltaY + gradientDeltaX * gradientDeltaX);
@@ -399,16 +431,16 @@ void GraphicsDriver::DrawRectangleNative(
399431 scaleGradientTopLeft = 0 ;
400432 scaleGradientTopRight = LIMIT - scalar;
401433 scaleGradientBottomLeft = scalar;
402- gradientTopLeftX = brush.gradientStartX - insetX ;
403- gradientTopLeftY = brush.gradientStartY - insetY ;
434+ gradientTopLeftX = brush.gradientStartX - x ;
435+ gradientTopLeftY = brush.gradientStartY - y ;
404436 }
405437 else
406438 {
407439 scaleGradientTopLeft = scalar;
408440 scaleGradientTopRight = LIMIT;
409441 scaleGradientBottomLeft = 0 ;
410- gradientTopLeftX = brush.gradientStartX - insetX ;
411- gradientTopLeftY = brush.gradientEndY - insetY ;
442+ gradientTopLeftX = brush.gradientStartX - x ;
443+ gradientTopLeftY = brush.gradientEndY - y ;
412444 }
413445
414446 int diffX = 0 ;
@@ -424,12 +456,13 @@ void GraphicsDriver::DrawRectangleNative(
424456 DivHelper widthDivHelper (scaleGradientTopRight - scaleGradientTopLeft, gradientDeltaX, 0 );
425457 DivHelper heightDivHelper (scaleGradientBottomLeft - scaleGradientTopLeft, gradientDeltaY, scaleLeft);
426458
427- for (int j = 0 ; j < insetHeight ; j++, curRow += stride)
459+ for (int j = 0 ; j < height ; j++, curRow += stride)
428460 {
429461 widthDivHelper.Reset (heightDivHelper.Next ());
430462
431463 CLR_UINT16 *curPixel = curRow;
432- for (int i = 0 ; i < insetWidth; i++, curPixel++)
464+
465+ for (int i = 0 ; i < width; i++, curPixel++)
433466 {
434467 int scale = widthDivHelper.Next ();
435468
@@ -468,7 +501,7 @@ void GraphicsDriver::DrawRectangleNative(
468501 }
469502 }
470503 }
471- } // (opacity != 0)
504+ }
472505}
473506
474507void GraphicsDriver::DrawRoundedRectangleNative (
@@ -507,16 +540,39 @@ void GraphicsDriver::DrawRoundedRectangleNative(
507540 return ;
508541
509542 params.pen = &pen;
510- params.brush = NULL ;
543+ params.brush = &brush;
544+
545+ // Fill
546+ if (brush.opacity != PAL_GFX_Bitmap::c_OpacityTransparent)
547+ {
548+ int gradientDeltaY = brush.gradientEndY - brush.gradientStartY ;
549+ int gradientDeltaX = brush.gradientEndX - brush.gradientStartX ;
550+
551+ if (brush.gradientStartColor == brush.gradientEndColor || (gradientDeltaX == 0 && gradientDeltaY == 0 ))
552+ {
553+ EllipseAlgorithm (bitmap, radiusX, radiusY, ¶ms, &Fill4PointLinesRoundedRect);
554+ }
555+ else
556+ {
557+ EllipseAlgorithm (bitmap, radiusX, radiusY, ¶ms, &GradientFill4PointLinesRoundedRect);
558+ }
559+
560+ GFX_Rect fillRect;
561+
562+ fillRect.left = x + pen.thickness ;
563+ fillRect.top = rectangle.top + radiusY + 1 ;
564+ fillRect.right = x2 - 1 - pen.thickness ;
565+ fillRect.bottom = rectangle.bottom - radiusY - 1 ;
566+
567+ FillRectangleNative (bitmap, brush, fillRect);
568+ }
511569
512570 EllipseAlgorithm (bitmap, radiusX, radiusY, ¶ms, &Draw4PointsRoundedRect);
513571
514572 DrawBresLineNative (bitmap, params.x1 , y, params.x2 , y, pen);
515573 DrawBresLineNative (bitmap, x, params.y1 , x, params.y2 , pen);
516574 DrawBresLineNative (bitmap, x2, params.y1 , x2, params.y2 , pen);
517575 DrawBresLineNative (bitmap, params.x1 , y2, params.x2 , y2, pen);
518-
519- // TODO - fill rounded rectangle
520576 }
521577}
522578
@@ -546,6 +602,48 @@ void GraphicsDriver::Draw4PointsRoundedRect(const PAL_GFX_Bitmap &bitmap, int of
546602 }
547603}
548604
605+ void GraphicsDriver::Fill4PointLinesRoundedRect (const PAL_GFX_Bitmap &bitmap, int offsetX, int offsetY, void *params)
606+ {
607+ Draw4PointsRoundedRectParams *p = (Draw4PointsRoundedRectParams *)params;
608+
609+ CLR_UINT32 color = p->brush ->gradientStartColor ;
610+ CLR_UINT16 opacity = p->brush ->opacity ;
611+
612+ // Top line
613+ DrawScanlineNative (bitmap, p->x1 - offsetX, p->x2 + offsetX, p->y1 - offsetY, color, opacity);
614+
615+ // Bottom line
616+ DrawScanlineNative (bitmap, p->x1 - offsetX, p->x2 + offsetX, p->y2 + offsetY, color, opacity);
617+ }
618+
619+ void GraphicsDriver::GradientFill4PointLinesRoundedRect (
620+ const PAL_GFX_Bitmap &bitmap,
621+ int offsetX,
622+ int offsetY,
623+ void *params)
624+ {
625+ Draw4PointsRoundedRectParams *p = (Draw4PointsRoundedRectParams *)params;
626+
627+ // Using the rectangle code for gradient fills. A version of DrawScanlineNative that supports gradients would be
628+ // faster
629+
630+ GFX_Rect rectangle;
631+
632+ // Top line
633+ rectangle.left = p->x1 - offsetX;
634+ rectangle.right = p->x2 + offsetX - 1 ;
635+ rectangle.top = p->y1 - offsetY;
636+ rectangle.bottom = rectangle.top ;
637+
638+ FillRectangleNative (bitmap, *(p->brush ), rectangle);
639+
640+ // Bottom line
641+ rectangle.top = p->y2 + offsetY;
642+ rectangle.bottom = rectangle.top ;
643+
644+ FillRectangleNative (bitmap, *(p->brush ), rectangle);
645+ }
646+
549647void GraphicsDriver::DrawEllipseNative (
550648 const PAL_GFX_Bitmap &bitmap,
551649 GFX_Pen &pen,
@@ -1220,6 +1318,46 @@ void GraphicsDriver::DrawBresLineNative(const PAL_GFX_Bitmap &bitmap, int x0, in
12201318 }
12211319}
12221320
1321+ void GraphicsDriver::DrawScanlineNative (
1322+ const PAL_GFX_Bitmap &bitmap,
1323+ int x1,
1324+ int x2,
1325+ int y,
1326+ CLR_UINT32 color,
1327+ CLR_UINT16 opacity)
1328+ {
1329+ // Check clipping
1330+ if ((y < bitmap.clipping .top ) || (y >= bitmap.clipping .bottom ))
1331+ {
1332+ return ;
1333+ }
1334+
1335+ if (x1 < bitmap.clipping .left )
1336+ x1 = bitmap.clipping .left ;
1337+
1338+ if (x2 >= bitmap.clipping .right )
1339+ x2 = bitmap.clipping .right - 1 ;
1340+
1341+ int stride = GetWidthInWords (bitmap.width ) * 2 ;
1342+
1343+ CLR_UINT16 *curPixel = ((CLR_UINT16 *)bitmap.data ) + (stride * y) + x1;
1344+
1345+ if (opacity == PAL_GFX_Bitmap::c_OpacityOpaque)
1346+ {
1347+ for (int x = x1; x <= x2; x++, curPixel++)
1348+ {
1349+ *curPixel = color;
1350+ }
1351+ }
1352+ else
1353+ {
1354+ for (int x = x1; x <= x2; x++, curPixel++)
1355+ {
1356+ *curPixel = g_GraphicsDriver.NativeColorInterpolate (color, *curPixel, opacity);
1357+ }
1358+ }
1359+ }
1360+
12231361void GraphicsDriver::EllipseAlgorithm (
12241362 const PAL_GFX_Bitmap &bitmap,
12251363 int radiusX,
0 commit comments