ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

BOOL FASTCALL PATH_Arc ( PDC  dc,
INT  x1,
INT  y1,
INT  x2,
INT  y2,
INT  xStart,
INT  yStart,
INT  xEnd,
INT  yEnd,
INT  lines 
)

Definition at line 496 of file path.c.

Referenced by IntGdiArcInternal(), and PATH_Ellipse().

{
  double  angleStart, angleEnd, angleStartQuadrant, angleEndQuadrant=0.0;
          /* Initialize angleEndQuadrant to silence gcc's warning */
  double  x, y;
  FLOAT_POINT corners[2], pointStart, pointEnd;
  POINT   centre, pointCurPos;
  BOOL    start, end, Ret = TRUE;
  INT     temp;
  BOOL    clockwise;
  PPATH   pPath;

  /* FIXME: This function should check for all possible error returns */
  /* FIXME: Do we have to respect newStroke? */

  ASSERT ( dc );

  pPath = PATH_LockPath( dc->dclevel.hPath );
  if (!pPath) return FALSE;

  clockwise = ((dc->dclevel.flPath & DCPATH_CLOCKWISE) != 0);

  /* Check that path is open */
  if ( pPath->state != PATH_Open )
  {
    Ret = FALSE;
    goto ArcExit;
  }

  /* Check for zero height / width */
  /* FIXME: Only in GM_COMPATIBLE? */
  if ( x1==x2 || y1==y2 )
  {
    Ret = TRUE;
    goto ArcExit;
  }
  /* Convert points to device coordinates */
  corners[0].x=(FLOAT)x1;
  corners[0].y=(FLOAT)y1;
  corners[1].x=(FLOAT)x2;
  corners[1].y=(FLOAT)y2;
  pointStart.x=(FLOAT)xStart;
  pointStart.y=(FLOAT)yStart;
  pointEnd.x=(FLOAT)xEnd;
  pointEnd.y=(FLOAT)yEnd;
  INTERNAL_LPTODP_FLOAT(dc, corners);
  INTERNAL_LPTODP_FLOAT(dc, corners+1);
  INTERNAL_LPTODP_FLOAT(dc, &pointStart);
  INTERNAL_LPTODP_FLOAT(dc, &pointEnd);

  /* Make sure first corner is top left and second corner is bottom right */
  if ( corners[0].x > corners[1].x )
  {
    temp=corners[0].x;
    corners[0].x=corners[1].x;
    corners[1].x=temp;
  }
  if ( corners[0].y > corners[1].y )
  {
    temp=corners[0].y;
    corners[0].y=corners[1].y;
    corners[1].y=temp;
  }

  /* Compute start and end angle */
  PATH_NormalizePoint(corners, &pointStart, &x, &y);
  angleStart=atan2(y, x);
  PATH_NormalizePoint(corners, &pointEnd, &x, &y);
  angleEnd=atan2(y, x);

  /* Make sure the end angle is "on the right side" of the start angle */
  if ( clockwise )
  {
    if ( angleEnd <= angleStart )
    {
      angleEnd+=2*M_PI;
      ASSERT(angleEnd>=angleStart);
    }
  }
  else
  {
    if(angleEnd>=angleStart)
    {
      angleEnd-=2*M_PI;
      ASSERT(angleEnd<=angleStart);
    }
  }

  /* In GM_COMPATIBLE, don't include bottom and right edges */
  if (dc->pdcattr->iGraphicsMode == GM_COMPATIBLE )
  {
    corners[1].x--;
    corners[1].y--;
  }

  /* arcto: Add a PT_MOVETO only if this is the first entry in a stroke */
  if(lines==GdiTypeArcTo && pPath->newStroke) // -1
  {
     pPath->newStroke=FALSE;
     IntGetCurrentPositionEx ( dc, &pointCurPos );
     CoordLPtoDP(dc, &pointCurPos);
     if(!PATH_AddEntry(pPath, &pointCurPos, PT_MOVETO))
     {
       Ret = FALSE;
       goto ArcExit;
     }
  }

  /* Add the arc to the path with one Bezier spline per quadrant that the
   * arc spans */
  start=TRUE;
  end=FALSE;
  do
  {
    /* Determine the start and end angles for this quadrant */
    if(start)
    {
      angleStartQuadrant=angleStart;
      if ( clockwise )
        angleEndQuadrant=(floor(angleStart/M_PI_2)+1.0)*M_PI_2;
      else
        angleEndQuadrant=(ceil(angleStart/M_PI_2)-1.0)*M_PI_2;
    }
    else
    {
      angleStartQuadrant=angleEndQuadrant;
      if ( clockwise )
        angleEndQuadrant+=M_PI_2;
      else
        angleEndQuadrant-=M_PI_2;
    }

    /* Have we reached the last part of the arc? */
    if ( (clockwise && angleEnd<angleEndQuadrant)
      || (!clockwise && angleEnd>angleEndQuadrant)
      )
    {
      /* Adjust the end angle for this quadrant */
     angleEndQuadrant = angleEnd;
     end = TRUE;
    }

    /* Add the Bezier spline to the path */
    PATH_DoArcPart ( pPath, corners, angleStartQuadrant, angleEndQuadrant,
       start ? (lines==GdiTypeArcTo ? PT_LINETO : PT_MOVETO) : FALSE ); // -1
    start = FALSE;
  } while(!end);

  /* chord: close figure. pie: add line and close figure */
  if (lines==GdiTypeChord) // 1
  {
      IntGdiCloseFigure(pPath);
  }
  else if (lines==GdiTypePie) // 2
  {
      centre.x = (corners[0].x+corners[1].x)/2;
      centre.y = (corners[0].y+corners[1].y)/2;
      if(!PATH_AddEntry(pPath, &centre, PT_LINETO | PT_CLOSEFIGURE))
         Ret = FALSE;
  }
ArcExit:
  PATH_UnlockPath( pPath );
  return Ret;
}

Generated on Sat May 26 2012 06:10:00 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.