Пример #1
0
void CFDE_Path::ArcTo(FX_BOOL bStart,
                      const CFX_RectF& rect,
                      FX_FLOAT startAngle,
                      FX_FLOAT endAngle) {
  FX_FLOAT rx = rect.width / 2;
  FX_FLOAT ry = rect.height / 2;
  FX_FLOAT cx = rect.left + rx;
  FX_FLOAT cy = rect.top + ry;
  FX_FLOAT alpha =
      FXSYS_atan2(rx * FXSYS_sin(startAngle), ry * FXSYS_cos(startAngle));
  FX_FLOAT beta =
      FXSYS_atan2(rx * FXSYS_sin(endAngle), ry * FXSYS_cos(endAngle));
  if (FXSYS_fabs(beta - alpha) > FX_PI) {
    if (beta > alpha)
      beta -= 2 * FX_PI;
    else
      alpha -= 2 * FX_PI;
  }
  FX_FLOAT half_delta = (beta - alpha) / 2;
  FX_FLOAT bcp = 4.0f / 3 * (1 - FXSYS_cos(half_delta)) / FXSYS_sin(half_delta);
  FX_FLOAT sin_alpha = FXSYS_sin(alpha);
  FX_FLOAT sin_beta = FXSYS_sin(beta);
  FX_FLOAT cos_alpha = FXSYS_cos(alpha);
  FX_FLOAT cos_beta = FXSYS_cos(beta);
  if (bStart)
    MoveTo(CFX_PointF(cx + rx * cos_alpha, cy + ry * sin_alpha));

  BezierTo(CFX_PointF(cx + rx * (cos_alpha - bcp * sin_alpha),
                      cy + ry * (sin_alpha + bcp * cos_alpha)),
           CFX_PointF(cx + rx * (cos_beta + bcp * sin_beta),
                      cy + ry * (sin_beta - bcp * cos_beta)),
           CFX_PointF(cx + rx * cos_beta, cy + ry * sin_beta));
}
Пример #2
0
void CFX_PathGenerator::ArcTo(FX_FLOAT x,
                              FX_FLOAT y,
                              FX_FLOAT width,
                              FX_FLOAT height,
                              FX_FLOAT start_angle,
                              FX_FLOAT sweep_angle) {
  FX_FLOAT x0 = FXSYS_cos(sweep_angle / 2);
  FX_FLOAT y0 = FXSYS_sin(sweep_angle / 2);
  FX_FLOAT tx = FXSYS_Div((1.0f - x0) * 4, 3 * 1.0f);
  FX_FLOAT ty = y0 - FXSYS_Div(FXSYS_Mul(tx, x0), y0);
  FX_FLOAT px[3], py[3];
  px[0] = x0 + tx;
  py[0] = -ty;
  px[1] = x0 + tx;
  py[1] = ty;
  FX_FLOAT sn = FXSYS_sin(start_angle + sweep_angle / 2);
  FX_FLOAT cs = FXSYS_cos(start_angle + sweep_angle / 2);
  int old_count = m_pPathData->GetPointCount();
  m_pPathData->AddPointCount(3);
  FX_FLOAT bezier_x, bezier_y;
  bezier_x = x + FXSYS_Mul(width, FXSYS_Mul(px[0], cs) - FXSYS_Mul(py[0], sn));
  bezier_y = y + FXSYS_Mul(height, FXSYS_Mul(px[0], sn) + FXSYS_Mul(py[0], cs));
  m_pPathData->SetPoint(old_count, bezier_x, bezier_y, FXPT_BEZIERTO);
  bezier_x = x + FXSYS_Mul(width, FXSYS_Mul(px[1], cs) - FXSYS_Mul(py[1], sn));
  bezier_y = y + FXSYS_Mul(height, FXSYS_Mul(px[1], sn) + FXSYS_Mul(py[1], cs));
  m_pPathData->SetPoint(old_count + 1, bezier_x, bezier_y, FXPT_BEZIERTO);
  bezier_x = x + FXSYS_Mul(width, FXSYS_cos(start_angle + sweep_angle)),
  bezier_y = y + FXSYS_Mul(height, FXSYS_sin(start_angle + sweep_angle));
  m_pPathData->SetPoint(old_count + 2, bezier_x, bezier_y, FXPT_BEZIERTO);
}
Пример #3
0
void CFX_PathGenerator::ArcTo(FX_FLOAT x,
                              FX_FLOAT y,
                              FX_FLOAT width,
                              FX_FLOAT height,
                              FX_FLOAT start_angle,
                              FX_FLOAT sweep_angle) {
  FX_FLOAT x0 = FXSYS_cos(sweep_angle / 2);
  FX_FLOAT y0 = FXSYS_sin(sweep_angle / 2);
  FX_FLOAT tx = ((1.0f - x0) * 4) / (3 * 1.0f);
  FX_FLOAT ty = y0 - ((tx * x0) / y0);
  FX_FLOAT px[3], py[3];
  px[0] = x0 + tx;
  py[0] = -ty;
  px[1] = x0 + tx;
  py[1] = ty;
  FX_FLOAT sn = FXSYS_sin(start_angle + sweep_angle / 2);
  FX_FLOAT cs = FXSYS_cos(start_angle + sweep_angle / 2);
  int old_count = m_pPathData->GetPointCount();
  m_pPathData->AddPointCount(3);
  FX_FLOAT bezier_x, bezier_y;
  bezier_x = x + (width * ((px[0] * cs) - (py[0] * sn)));
  bezier_y = y + (height * ((px[0] * sn) + (py[0] * cs)));
  m_pPathData->SetPoint(old_count, bezier_x, bezier_y, FXPT_BEZIERTO);
  bezier_x = x + (width * ((px[1] * cs) - (py[1] * sn)));
  bezier_y = y + (height * ((px[1] * sn) + (py[1] * cs)));
  m_pPathData->SetPoint(old_count + 1, bezier_x, bezier_y, FXPT_BEZIERTO);
  bezier_x = x + (width * FXSYS_cos(start_angle + sweep_angle));
  bezier_y = y + (height * FXSYS_sin(start_angle + sweep_angle));
  m_pPathData->SetPoint(old_count + 2, bezier_x, bezier_y, FXPT_BEZIERTO);
}
Пример #4
0
void CFX_Matrix::Rotate(FX_FLOAT fRadian, FX_BOOL bPrepended) {
    FX_FLOAT cosValue = FXSYS_cos(fRadian);
    FX_FLOAT sinValue = FXSYS_sin(fRadian);
    CFX_Matrix m;
    m.Set(cosValue, sinValue, -sinValue, cosValue, 0, 0);
    if (bPrepended) {
        FXCRT_Matrix_Concat(*this, m, *this);
    } else {
        FXCRT_Matrix_Concat(*this, *this, m);
    }
}
Пример #5
0
void CFX_PathGenerator::AddArc(FX_FLOAT x,
                               FX_FLOAT y,
                               FX_FLOAT width,
                               FX_FLOAT height,
                               FX_FLOAT start_angle,
                               FX_FLOAT sweep_angle) {
  if (sweep_angle == 0) {
    return;
  }

  const FX_FLOAT bezier_arc_angle_epsilon = 0.01f;
  while (start_angle > FX_PI * 2) {
    start_angle -= FX_PI * 2;
  }
  while (start_angle < 0) {
    start_angle += FX_PI * 2;
  }
  if (sweep_angle >= FX_PI * 2) {
    sweep_angle = FX_PI * 2;
  }
  if (sweep_angle <= -FX_PI * 2) {
    sweep_angle = -FX_PI * 2;
  }
  m_pPathData->AddPointCount(1);
  m_pPathData->SetPoint(m_pPathData->GetPointCount() - 1,
                        x + (width * FXSYS_cos(start_angle)),
                        y + (height * FXSYS_sin(start_angle)), FXPT_MOVETO);
  FX_FLOAT total_sweep = 0, local_sweep = 0, prev_sweep = 0;
  bool done = false;
  do {
    if (sweep_angle < 0) {
      prev_sweep = total_sweep;
      local_sweep = -FX_PI / 2;
      total_sweep -= FX_PI / 2;
      if (total_sweep <= sweep_angle + bezier_arc_angle_epsilon) {
        local_sweep = sweep_angle - prev_sweep;
        done = true;
      }
    } else {
      prev_sweep = total_sweep;
      local_sweep = FX_PI / 2;
      total_sweep += FX_PI / 2;
      if (total_sweep >= sweep_angle - bezier_arc_angle_epsilon) {
        local_sweep = sweep_angle - prev_sweep;
        done = true;
      }
    }
    ArcTo(x, y, width, height, start_angle, local_sweep);
    start_angle += local_sweep;
  } while (!done);
}
Пример #6
0
void CFX_PathGenerator::AddPie(FX_FLOAT x,
                               FX_FLOAT y,
                               FX_FLOAT width,
                               FX_FLOAT height,
                               FX_FLOAT start_angle,
                               FX_FLOAT sweep_angle) {
  if (sweep_angle == 0) {
    int old_count = m_pPathData->GetPointCount();
    m_pPathData->AddPointCount(2);
    m_pPathData->SetPoint(old_count, x, y, FXPT_MOVETO);
    m_pPathData->SetPoint(old_count + 1, x + (width * FXSYS_cos(start_angle)),
                          y + (height * FXSYS_sin(start_angle)), FXPT_LINETO);
    return;
  }
  AddArc(x, y, width, height, start_angle, sweep_angle);
  m_pPathData->AddPointCount(1);
  m_pPathData->SetPoint(m_pPathData->GetPointCount() - 1, x, y,
                        FXPT_LINETO | FXPT_CLOSEFIGURE);
}
Пример #7
0
FX_BOOL CPDF_PSEngine::DoOperator(PDF_PSOP op) {
  int i1, i2;
  FX_FLOAT d1, d2;
  switch (op) {
    case PSOP_ADD:
      d1 = Pop();
      d2 = Pop();
      Push(d1 + d2);
      break;
    case PSOP_SUB:
      d2 = Pop();
      d1 = Pop();
      Push(d1 - d2);
      break;
    case PSOP_MUL:
      d1 = Pop();
      d2 = Pop();
      Push(d1 * d2);
      break;
    case PSOP_DIV:
      d2 = Pop();
      d1 = Pop();
      Push(d1 / d2);
      break;
    case PSOP_IDIV:
      i2 = (int)Pop();
      i1 = (int)Pop();
      Push(i2 ? i1 / i2 : 0);
      break;
    case PSOP_MOD:
      i2 = (int)Pop();
      i1 = (int)Pop();
      Push(i2 ? i1 % i2 : 0);
      break;
    case PSOP_NEG:
      d1 = Pop();
      Push(-d1);
      break;
    case PSOP_ABS:
      d1 = Pop();
      Push((FX_FLOAT)FXSYS_fabs(d1));
      break;
    case PSOP_CEILING:
      d1 = Pop();
      Push((FX_FLOAT)FXSYS_ceil(d1));
      break;
    case PSOP_FLOOR:
      d1 = Pop();
      Push((FX_FLOAT)FXSYS_floor(d1));
      break;
    case PSOP_ROUND:
      d1 = Pop();
      Push(FXSYS_round(d1));
      break;
    case PSOP_TRUNCATE:
      i1 = (int)Pop();
      Push(i1);
      break;
    case PSOP_SQRT:
      d1 = Pop();
      Push((FX_FLOAT)FXSYS_sqrt(d1));
      break;
    case PSOP_SIN:
      d1 = Pop();
      Push((FX_FLOAT)FXSYS_sin(d1 * FX_PI / 180.0f));
      break;
    case PSOP_COS:
      d1 = Pop();
      Push((FX_FLOAT)FXSYS_cos(d1 * FX_PI / 180.0f));
      break;
    case PSOP_ATAN:
      d2 = Pop();
      d1 = Pop();
      d1 = (FX_FLOAT)(FXSYS_atan2(d1, d2) * 180.0 / FX_PI);
      if (d1 < 0) {
        d1 += 360;
      }
      Push(d1);
      break;
    case PSOP_EXP:
      d2 = Pop();
      d1 = Pop();
      Push((FX_FLOAT)FXSYS_pow(d1, d2));
      break;
    case PSOP_LN:
      d1 = Pop();
      Push((FX_FLOAT)FXSYS_log(d1));
      break;
    case PSOP_LOG:
      d1 = Pop();
      Push((FX_FLOAT)FXSYS_log10(d1));
      break;
    case PSOP_CVI:
      i1 = (int)Pop();
      Push(i1);
      break;
    case PSOP_CVR:
      break;
    case PSOP_EQ:
      d2 = Pop();
      d1 = Pop();
      Push((int)(d1 == d2));
      break;
    case PSOP_NE:
      d2 = Pop();
      d1 = Pop();
      Push((int)(d1 != d2));
      break;
    case PSOP_GT:
      d2 = Pop();
      d1 = Pop();
      Push((int)(d1 > d2));
      break;
    case PSOP_GE:
      d2 = Pop();
      d1 = Pop();
      Push((int)(d1 >= d2));
      break;
    case PSOP_LT:
      d2 = Pop();
      d1 = Pop();
      Push((int)(d1 < d2));
      break;
    case PSOP_LE:
      d2 = Pop();
      d1 = Pop();
      Push((int)(d1 <= d2));
      break;
    case PSOP_AND:
      i1 = (int)Pop();
      i2 = (int)Pop();
      Push(i1 & i2);
      break;
    case PSOP_OR:
      i1 = (int)Pop();
      i2 = (int)Pop();
      Push(i1 | i2);
      break;
    case PSOP_XOR:
      i1 = (int)Pop();
      i2 = (int)Pop();
      Push(i1 ^ i2);
      break;
    case PSOP_NOT:
      i1 = (int)Pop();
      Push((int)!i1);
      break;
    case PSOP_BITSHIFT: {
      int shift = (int)Pop();
      int i = (int)Pop();
      if (shift > 0) {
        Push(i << shift);
      } else {
        Push(i >> -shift);
      }
      break;
    }
    case PSOP_TRUE:
      Push(1);
      break;
    case PSOP_FALSE:
      Push(0);
      break;
    case PSOP_POP:
      Pop();
      break;
    case PSOP_EXCH:
      d2 = Pop();
      d1 = Pop();
      Push(d2);
      Push(d1);
      break;
    case PSOP_DUP:
      d1 = Pop();
      Push(d1);
      Push(d1);
      break;
    case PSOP_COPY: {
      int n = static_cast<int>(Pop());
      if (n < 0 || m_StackCount + n > PSENGINE_STACKSIZE ||
          n > static_cast<int>(m_StackCount))
        break;
      for (int i = 0; i < n; i++)
        m_Stack[m_StackCount + i] = m_Stack[m_StackCount + i - n];
      m_StackCount += n;
      break;
    }
    case PSOP_INDEX: {
      int n = static_cast<int>(Pop());
      if (n < 0 || n >= static_cast<int>(m_StackCount))
        break;
      Push(m_Stack[m_StackCount - n - 1]);
      break;
    }
    case PSOP_ROLL: {
      int j = static_cast<int>(Pop());
      int n = static_cast<int>(Pop());
      if (m_StackCount == 0)
        break;
      if (n < 0 || n > static_cast<int>(m_StackCount))
        break;
      if (j < 0) {
        for (int i = 0; i < -j; i++) {
          FX_FLOAT first = m_Stack[m_StackCount - n];
          for (int ii = 0; ii < n - 1; ii++)
            m_Stack[m_StackCount - n + ii] = m_Stack[m_StackCount - n + ii + 1];
          m_Stack[m_StackCount - 1] = first;
        }
      } else {
        for (int i = 0; i < j; i++) {
          FX_FLOAT last = m_Stack[m_StackCount - 1];
          int ii;
          for (ii = 0; ii < n - 1; ii++)
            m_Stack[m_StackCount - ii - 1] = m_Stack[m_StackCount - ii - 2];
          m_Stack[m_StackCount - ii - 1] = last;
        }
      }
      break;
    }
    default:
      break;
  }
  return TRUE;
}
Пример #8
0
void CFX_PathGenerator::AddArc(FX_FLOAT x,
                               FX_FLOAT y,
                               FX_FLOAT width,
                               FX_FLOAT height,
                               FX_FLOAT start_angle,
                               FX_FLOAT sweep_angle) {
#if 0
    FX_FIXFLOAT32 sweep = sweep_angle;
    while (sweep > FIXFLOAT32_PI * 2) {
        sweep -= FIXFLOAT32_PI * 2;
    }
    if (sweep == 0) {
        return;
    }
    m_pPathData->AddPointCount(1);
    m_pPathData->SetPoint(m_pPathData->GetPointCount() - 1,
                          x + fixmul_8_32_to_8(width, fixcos(start_angle)),
                          y + fixmul_8_32_to_8(height, fixsin(start_angle)), FXPT_MOVETO);
    FX_FIXFLOAT32 angle1 = 0, angle2;
    FX_BOOL bDone = FALSE;
    do {
        angle2 = angle1 + FIXFLOAT32_PI / 2;
        if (angle2 >= sweep) {
            angle2 = sweep;
            bDone = TRUE;
        }
        ArcTo(x, y, width, height, start_angle + angle1, angle2 - angle1);
        angle1 = angle2;
    } while (!bDone);
#else
  if (sweep_angle == 0) {
    return;
  }
  static const FX_FLOAT bezier_arc_angle_epsilon = (FX_FLOAT)(0.01f);
  while (start_angle > FX_PI * 2) {
    start_angle -= FX_PI * 2;
  }
  while (start_angle < 0) {
    start_angle += FX_PI * 2;
  }
  if (sweep_angle >= FX_PI * 2) {
    sweep_angle = FX_PI * 2;
  }
  if (sweep_angle <= -FX_PI * 2) {
    sweep_angle = -FX_PI * 2;
  }
  m_pPathData->AddPointCount(1);
  m_pPathData->SetPoint(m_pPathData->GetPointCount() - 1,
                        x + FXSYS_Mul(width, FXSYS_cos(start_angle)),
                        y + FXSYS_Mul(height, FXSYS_sin(start_angle)),
                        FXPT_MOVETO);
  FX_FLOAT total_sweep = 0, local_sweep = 0, prev_sweep = 0;
  FX_BOOL done = FALSE;
  do {
    if (sweep_angle < 0) {
      prev_sweep = total_sweep;
      local_sweep = -FX_PI / 2;
      total_sweep -= FX_PI / 2;
      if (total_sweep <= sweep_angle + bezier_arc_angle_epsilon) {
        local_sweep = sweep_angle - prev_sweep;
        done = TRUE;
      }
    } else {
      prev_sweep = total_sweep;
      local_sweep = FX_PI / 2;
      total_sweep += FX_PI / 2;
      if (total_sweep >= sweep_angle - bezier_arc_angle_epsilon) {
        local_sweep = sweep_angle - prev_sweep;
        done = TRUE;
      }
    }
    ArcTo(x, y, width, height, start_angle, local_sweep);
    start_angle += local_sweep;
  } while (!done);
#endif
}