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)); }
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); }
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); }
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); } }
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); }
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); }
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; }
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 }