void
PathBuilderNVpr::Close()
{
  MakeWritable();

  mDescription.AppendCommand(GL_CLOSE_PATH_NV);

  mCurrentPoint = mStartPoint;
}
Beispiel #2
0
bool EnsureWritablePagesNoThrow(void* p, size_t len)
{
    BYTE* pStart = (BYTE*)p;

    if (len == 0)
        return true;

    if (!AreAnyCOWPageBitsSet(pStart, len))
        return true;

    return MakeWritable(pStart, len, PAGE_READWRITE);
}
void
PathBuilderNVpr::Arc(const Point& aOrigin, Float aRadius, Float aStartAngle,
                     Float aEndAngle, bool aAntiClockwise)
{
  MakeWritable();

  const Point startPoint(aOrigin.x + cos(aStartAngle) * aRadius,
                         aOrigin.y + sin(aStartAngle) * aRadius);

  // The spec says to begin with a line to the start point.
  LineTo(startPoint);

  mIsPolygon = false;

  if (fabs(aEndAngle - aStartAngle) > 2 * M_PI - 1e-5) {
    // The spec says to just draw the whole circle in this case.
    mDescription.AppendCommand(GL_CIRCULAR_CCW_ARC_TO_NV);
    mDescription.AppendPoint(aOrigin);
    mDescription.AppendFloat(aRadius);
    mDescription.AppendFloat(aStartAngle * 180 / M_PI);
    mDescription.AppendFloat(360 + aStartAngle * 180 / M_PI);
    return;
  }

  const Point endPoint(aOrigin.x + cos(aEndAngle) * aRadius,
                       aOrigin.y + sin(aEndAngle) * aRadius);

  if (aAntiClockwise && aEndAngle < aStartAngle) {
    aEndAngle += 2 * M_PI;
  } else if (!aAntiClockwise && aEndAngle > aStartAngle) {
    aEndAngle -= 2 * M_PI;
  }

  // 'Anticlockwise' in HTML5 seems to be relative to a downward-pointing Y-axis,
  // whereas CW/CCW are relative to an upward-facing Y-axis in NV_path_rendering.
  if (fabs(aEndAngle - aStartAngle) < M_PI) {
    mDescription.AppendCommand(aAntiClockwise ? GL_LARGE_CW_ARC_TO_NV
                                              : GL_LARGE_CCW_ARC_TO_NV);
  } else {
    mDescription.AppendCommand(aAntiClockwise ? GL_SMALL_CW_ARC_TO_NV
                                              : GL_SMALL_CCW_ARC_TO_NV);
  }
  mDescription.AppendFloat(aRadius); // x-radius
  mDescription.AppendFloat(aRadius); // y-radius
  mDescription.AppendFloat(0);
  mDescription.AppendPoint(endPoint);

  mCurrentPoint = endPoint;
}
void
PathBuilderNVpr::MoveTo(const Point& aPoint)
{
  MakeWritable();

  if (!mDescription.IsEmpty()) {
    mIsPolygon = false;
  }

  mDescription.AppendCommand(GL_MOVE_TO_NV);
  mDescription.AppendPoint(aPoint);

  mStartPoint = aPoint;
  mCurrentPoint = aPoint;
}
void
PathBuilderNVpr::QuadraticBezierTo(const Point& aCP1,
                                   const Point& aCP2)
{
  MakeWritable();

  if (mDescription.IsEmpty()) {
    MoveTo(aCP1);
  }

  mDescription.AppendCommand(GL_QUADRATIC_CURVE_TO_NV);
  mDescription.AppendPoint(aCP1);
  mDescription.AppendPoint(aCP2);

  mCurrentPoint = aCP2;

  mIsPolygon = false;
}
void
PathBuilderNVpr::LineTo(const Point& aPoint)
{
  MakeWritable();

  if (mDescription.IsEmpty()) {
    MoveTo(aPoint);
    return;
  }

  if (mDescription.mCommands.back() != GL_MOVE_TO_NV
      && mDescription.mCommands.back() != GL_LINE_TO_NV) {
    mIsPolygon = false;
  }

  mDescription.AppendCommand(GL_LINE_TO_NV);
  mDescription.AppendPoint(aPoint);

  mCurrentPoint = aPoint;
}