LCOV - code coverage report
Current view: top level - src - primrect.c (source / functions) Hit Total Coverage
Test: cov_nosys.info Lines: 73 96 76.0 %
Date: 2024-06-16 08:54:54 Functions: 9 12 75.0 %

          Line data    Source code
       1             : /*
       2             :  *  primrect.c
       3             :  *  Patater GUI Kit
       4             :  *
       5             :  *  Created by Jaeden Amero on 2021-01-15.
       6             :  *  Copyright 2021. SPDX-License-Identifier: AGPL-3.0-or-later
       7             :  */
       8             : 
       9             : #include "guikit/primrect.h"
      10             : 
      11          12 : static int min(int a, int b)
      12             : {
      13          12 :     return a < b ? a : b;
      14             : }
      15             : 
      16          12 : static int max(int a, int b)
      17             : {
      18          12 :     return a > b ? a : b;
      19             : }
      20             : 
      21           0 : void InitRect(struct Rect *rect, int x, int y, int w, int h)
      22             : {
      23           0 :     rect->left = x;
      24           0 :     rect->top = y;
      25           0 :     rect->right = x + w - 1;
      26           0 :     rect->bottom = y + h - 1;
      27           0 : }
      28             : 
      29           4 : void RectFromLine(struct Rect *rect, int x0, int y0, int x1, int y1)
      30             : {
      31             :     /* Create the smallest rectangle that will contain the line segment. */
      32           4 :     rect->left = min(x0, x1);
      33           4 :     rect->top = min(y0, y1);
      34           4 :     rect->right = max(x0, x1);
      35           4 :     rect->bottom = max(y0, y1);
      36           4 : }
      37             : 
      38           4 : void NormalizedRect(struct Rect *rect, const struct Rect *r)
      39             : {
      40           4 :     RectFromLine(rect, r->left, r->top, r->right, r->bottom);
      41           4 : }
      42             : 
      43           6 : static int RectIsEmpty(const struct Rect *rect)
      44             : {
      45             :     /* XXX Change this when making bottom inclusive */
      46           6 :     if (rect->bottom <= rect->top)
      47             :     {
      48           3 :         return 1;
      49             :     }
      50             : 
      51           3 :     if (rect->right <= rect->left)
      52             :     {
      53           0 :         return 1;
      54             :     }
      55             : 
      56           3 :     return 0;
      57             : }
      58             : 
      59           4 : int RectUnion(const struct Rect *a, const struct Rect *b, struct Rect *u)
      60             : {
      61           4 :     if (RectIsEmpty(a))
      62             :     {
      63           2 :         *u = *b;
      64           2 :         return 0;
      65             :     }
      66             : 
      67           2 :     if (RectIsEmpty(b))
      68             :     {
      69           1 :         *u = *a;
      70           1 :         return 0;
      71             :     }
      72             : 
      73           1 :     u->left = min(a->left, b->left);
      74           1 :     u->top = min(a->top, b->top);
      75           1 :     u->right = max(a->right, b->right);
      76           1 :     u->bottom = max(a->bottom, b->bottom);
      77             : 
      78           1 :     return 0;
      79             : }
      80             : 
      81           2 : int RectIntersect(const struct Rect *a, const struct Rect *b, struct Rect *i)
      82             : {
      83             :     /* Fast rejects */
      84           2 :     if (a->bottom < b->top)
      85             :     {
      86           1 :         return RECT_NO_INTERSECT;
      87             :     }
      88           1 :     if (a->right < b->left)
      89             :     {
      90           0 :         return RECT_NO_INTERSECT;
      91             :     }
      92           1 :     if (a->top > b->bottom)
      93             :     {
      94           0 :         return RECT_NO_INTERSECT;
      95             :     }
      96           1 :     if (a->left > b->right)
      97             :     {
      98           0 :         return RECT_NO_INTERSECT;
      99             :     }
     100             : 
     101           1 :     i->left = max(a->left, b->left);
     102           1 :     i->top = max(a->top, b->top);
     103           1 :     i->right = min(a->right, b->right);
     104           1 :     i->bottom = min(a->bottom, b->bottom);
     105             : 
     106           1 :     return RECT_INTERSECT;
     107             : }
     108             : 
     109           0 : void ConvertRect(const struct Rect *rect, int *x, int *y, int *w, int *h)
     110             : {
     111           0 :     *x = rect->left;
     112           0 :     *y = rect->top;
     113           0 :     *w = rect->right - rect->left + 1;
     114           0 :     *h = rect->bottom - rect->top + 1;
     115           0 : }
     116             : 
     117           0 : void TranslateRect(struct Rect *rect, int x, int y)
     118             : {
     119           0 :     rect->left += x;
     120           0 :     rect->top += y;
     121           0 :     rect->right += x;
     122           0 :     rect->bottom += y;
     123           0 : }
     124             : 
     125             : #if 0
     126             : int PushClip(struct Rect *rect, const struct Rect *clip)
     127             : {
     128             :     /* Clip rect to clip */
     129             : }
     130             : 
     131             : int PopClip(struct Rect *rect, const struct Rect *clip)
     132             : {
     133             :     /* Restore previously pushed onto clip */
     134             : }
     135             : #endif
     136             : 
     137          18 : int ClipRect(struct Rect *rect, const struct Rect *clip)
     138             : {
     139          18 :     int ret = CLIP_NO_CHANGE;
     140             : 
     141             :     /* Fast rejects */
     142          18 :     if (rect->bottom < clip->top)
     143             :     {
     144             : #define DEBUG 0
     145             : #if DEBUG
     146             :         SerialPrintf("Too high\n");
     147             : #endif
     148           3 :         return CLIP_REJECTED;
     149             :     }
     150          15 :     if (rect->right < clip->left)
     151             :     {
     152             : #if DEBUG
     153             :         SerialPrintf("Too far left\n");
     154             : #endif
     155           2 :         return CLIP_REJECTED;
     156             :     }
     157          13 :     if (rect->top > clip->bottom)
     158             :     {
     159             : #if DEBUG
     160             :         SerialPrintf("Too low\n");
     161             : #endif
     162           1 :         return CLIP_REJECTED;
     163             :     }
     164          12 :     if (rect->left > clip->right)
     165             :     {
     166             : #if DEBUG
     167             :         SerialPrintf("Too far right\n");
     168             : #endif
     169           2 :         return CLIP_REJECTED;
     170             :     }
     171             : 
     172             :     /* Clips */
     173          10 :     if (rect->top < clip->top)
     174             :     {
     175           3 :         rect->top = clip->top;
     176           3 :         ret = CLIP_CLIPPED;
     177             :     }
     178          10 :     if (rect->left < clip->left)
     179             :     {
     180           3 :         rect->left = clip->left;
     181           3 :         ret = CLIP_CLIPPED;
     182             :     }
     183          10 :     if (rect->right > clip->right)
     184             :     {
     185           4 :         rect->right = clip->right;
     186           4 :         ret = CLIP_CLIPPED;
     187             :     }
     188          10 :     if (rect->bottom > clip->bottom)
     189             :     {
     190           4 :         rect->bottom = clip->bottom;
     191           4 :         ret = CLIP_CLIPPED;
     192             :     }
     193             : 
     194          10 :     return ret;
     195             : #if WE_COULD_USE_INTERSECT
     196             :     int ret;
     197             : 
     198             :     ret = RectIntersect(rect, clip, rect);
     199             :     if (ret == RECT_INTERSECT)
     200             :     {
     201             :         return CLIP_CLIPPED;
     202             :     }
     203             : 
     204             :     return CLIP_REJECTED;
     205             : #endif
     206             : }
     207             : 
     208           1 : int ClipRectAdjust(struct Rect *dst, struct Rect *src, const struct Rect *clip)
     209             : {
     210             :     int ret;
     211             : 
     212             :     /* Clip the dst rect based on the clipping rect. */
     213             :     /* Adjust the src rect based on how the dst rect was clipped. */
     214             : 
     215             :     struct Rect orig;
     216             : 
     217             :     /* Adjust dst clipping */
     218           1 :     orig = *dst;
     219           1 :     ret = ClipRect(dst, clip);
     220           1 :     if (ret == CLIP_REJECTED)
     221             :     {
     222           0 :         return CLIP_REJECTED;
     223             :     }
     224             : 
     225             :     /* Adjust src based on dst clipping */
     226           1 :     src->left += dst->left - orig.left; /* new_val - orig_val */
     227           1 :     src->top += dst->top - orig.top; /* new_val - orig_val */
     228           1 :     src->right -= (orig.right - dst->right);
     229           1 :     src->bottom -= (orig.bottom - dst->bottom);
     230             : 
     231           1 :     return CLIP_CLIPPED;
     232             : }

Generated by: LCOV version 1.14