inline FX_FLOAT _GetDistance(CFX_FloatRect floatRect, CPDF_Point point) { if(floatRect.right < point.x && floatRect.bottom > point.y) { return FXSYS_sqrt(FXSYS_pow(point.x - floatRect.right, 2) + FXSYS_pow(floatRect.bottom - point.y, 2)); } if (floatRect.right < point.x && floatRect.top < point.y) { return FXSYS_sqrt(FXSYS_pow(point.x - floatRect.right, 2) + FXSYS_pow(point.y - floatRect.top, 2)); } if(floatRect.left > point.x && floatRect.bottom > point.y) { return FXSYS_sqrt(FXSYS_pow(floatRect.bottom - point.y, 2) + FXSYS_pow(floatRect.left - point.x, 2)); } if((floatRect.right > point.x || FXSYS_fabs(floatRect.right - point.x) <= 0.0001f) && (floatRect.left < point.x || FXSYS_fabs(floatRect.left - point.x) <= 0.0001f) && floatRect.bottom > point.y) { return FXSYS_fabs(floatRect.bottom - point.y); } if(floatRect.left > point.x && (floatRect.bottom < point.y || FXSYS_fabs(floatRect.bottom - point.y) <= 0.0001f) && (floatRect.top > point.y || FXSYS_fabs(floatRect.top - point.y) <= 0.0001f)) { return FXSYS_fabs(floatRect.left - point.x); } if(floatRect.left > point.x && floatRect.top < point.y) { return FXSYS_sqrt(FXSYS_pow(floatRect.left - point.x, 2) + FXSYS_pow(point.y - floatRect.top, 2)); } if ((floatRect.left < point.x || FXSYS_fabs(floatRect.left - point.x) <= 0.0001f) && (floatRect.right > point.x || FXSYS_fabs(floatRect.right - point.x) <= 0.0001f) && floatRect.top < point.y) { return FXSYS_fabs(point.y - floatRect.top); } if(floatRect.right < point.x && (floatRect.top > point.y || FXSYS_fabs(floatRect.top - point.y) <= 0.0001f) && (floatRect.bottom < point.y || FXSYS_fabs(floatRect.bottom - point.y) <= 0.0001f)) { return point.x - floatRect.right; } return .0f; }
FX_FLOAT CFX_Matrix::GetUnitArea() const { FX_FLOAT A = FXSYS_sqrt(a * a + b * b); FX_FLOAT B = FXSYS_sqrt(c * c + d * d); FX_FLOAT ac = a + c, bd = b + d; FX_FLOAT C = FXSYS_sqrt(ac * ac + bd * bd); FX_FLOAT P = (A + B + C) / 2; return FXSYS_sqrt(P * (P - A) * (P - B) * (P - C)) * 2; }
FX_FLOAT CFX_Matrix::GetYUnit() const { if (c == 0) { return (d > 0 ? d : -d); } if (d == 0) { return (c > 0 ? c : -c); } return FXSYS_sqrt(c * c + d * d); }
FX_FLOAT CFX_Matrix::GetXUnit() const { if (b == 0) { return (a > 0 ? a : -a); } if (a == 0) { return (b > 0 ? b : -b); } return FXSYS_sqrt(a * a + b * b); }
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; }
int32_t CFX_Matrix::TransformDistance(int32_t dx, int32_t dy) const { FX_FLOAT fx = a * dx + c * dy, fy = b * dx + d * dy; return FXSYS_round(FXSYS_sqrt(fx * fx + fy * fy)); }
FX_FLOAT CFX_Matrix::TransformDistance(FX_FLOAT dx, FX_FLOAT dy) const { FX_FLOAT fx = a * dx + c * dy, fy = b * dx + d * dy; return FXSYS_sqrt(fx * fx + fy * fy); }
FX_FLOAT CFX_Matrix::TransformYDistance(FX_FLOAT dy) const { FX_FLOAT fx = c * dy, fy = d * dy; return FXSYS_sqrt(fx * fx + fy * fy); }
int32_t CFX_Matrix::TransformXDistance(int32_t dx) const { FX_FLOAT fx = a * dx, fy = b * dx; return FXSYS_round(FXSYS_sqrt(fx * fx + fy * fy)); }
FX_FLOAT CFX_Matrix::TransformXDistance(FX_FLOAT dx) const { FX_FLOAT fx = a * dx, fy = b * dx; return FXSYS_sqrt(fx * fx + fy * fy); }
static CFX_DIBitmap* Transform1bppBitmap(const CFX_DIBSource* pSrc, const CFX_AffineMatrix* pDestMatrix) { ASSERT(pSrc->GetFormat() == FXDIB_1bppRgb || pSrc->GetFormat() == FXDIB_1bppMask || pSrc->GetFormat() == FXDIB_1bppCmyk); CFX_DIBExtractor src_bitmap(pSrc); CFX_DIBitmap* pSrcBitmap = src_bitmap; if (pSrcBitmap == NULL) { return NULL; } int src_width = pSrcBitmap->GetWidth(), src_height = pSrcBitmap->GetHeight(); uint8_t* src_buf = pSrcBitmap->GetBuffer(); FX_DWORD src_pitch = pSrcBitmap->GetPitch(); FX_FLOAT dest_area = pDestMatrix->GetUnitArea(); FX_FLOAT area_scale = FXSYS_Div((FX_FLOAT)(src_width * src_height), dest_area); FX_FLOAT size_scale = FXSYS_sqrt(area_scale); CFX_AffineMatrix adjusted_matrix(*pDestMatrix); adjusted_matrix.Scale(size_scale, size_scale); CFX_FloatRect result_rect_f = adjusted_matrix.GetUnitRect(); FX_RECT result_rect = result_rect_f.GetOutterRect(); CFX_AffineMatrix src2result; src2result.e = adjusted_matrix.c + adjusted_matrix.e; src2result.f = adjusted_matrix.d + adjusted_matrix.f; src2result.a = adjusted_matrix.a / pSrcBitmap->GetWidth(); src2result.b = adjusted_matrix.b / pSrcBitmap->GetWidth(); src2result.c = -adjusted_matrix.c / pSrcBitmap->GetHeight(); src2result.d = -adjusted_matrix.d / pSrcBitmap->GetHeight(); src2result.TranslateI(-result_rect.left, -result_rect.top); CFX_AffineMatrix result2src; result2src.SetReverse(src2result); CPDF_FixedMatrix result2src_fix(result2src, 8); int result_width = result_rect.Width(); int result_height = result_rect.Height(); CFX_DIBitmap* pTempBitmap = new CFX_DIBitmap; if (!pTempBitmap->Create(result_width, result_height, pSrc->GetFormat())) { delete pTempBitmap; if (pSrcBitmap != src_bitmap) { delete pSrcBitmap; } return NULL; } pTempBitmap->CopyPalette(pSrc->GetPalette()); uint8_t* dest_buf = pTempBitmap->GetBuffer(); int dest_pitch = pTempBitmap->GetPitch(); FXSYS_memset(dest_buf, pSrc->IsAlphaMask() ? 0 : 0xff, dest_pitch * result_height); if (pSrcBitmap->IsAlphaMask()) { for (int dest_y = 0; dest_y < result_height; dest_y++) { uint8_t* dest_scan = dest_buf + dest_y * dest_pitch; for (int dest_x = 0; dest_x < result_width; dest_x++) { int src_x, src_y; result2src_fix.Transform(dest_x, dest_y, src_x, src_y); if (src_x < 0 || src_x >= src_width || src_y < 0 || src_y >= src_height) { continue; } if (!((src_buf + src_pitch * src_y)[src_x / 8] & (1 << (7 - src_x % 8)))) { continue; } dest_scan[dest_x / 8] |= 1 << (7 - dest_x % 8); } } } else { for (int dest_y = 0; dest_y < result_height; dest_y++) { uint8_t* dest_scan = dest_buf + dest_y * dest_pitch; for (int dest_x = 0; dest_x < result_width; dest_x++) { int src_x, src_y; result2src_fix.Transform(dest_x, dest_y, src_x, src_y); if (src_x < 0 || src_x >= src_width || src_y < 0 || src_y >= src_height) { continue; } if ((src_buf + src_pitch * src_y)[src_x / 8] & (1 << (7 - src_x % 8))) { continue; } dest_scan[dest_x / 8] &= ~(1 << (7 - dest_x % 8)); } } } if (pSrcBitmap != src_bitmap) { delete pSrcBitmap; } return pTempBitmap; }
static void DrawRadialShading(CFX_DIBitmap* pBitmap, CFX_Matrix* pObject2Bitmap, CPDF_Dictionary* pDict, CPDF_Function** pFuncs, int nFuncs, CPDF_ColorSpace* pCS, int alpha) { ASSERT(pBitmap->GetFormat() == FXDIB_Argb); CPDF_Array* pCoords = pDict->GetArray("Coords"); if (!pCoords) { return; } FX_FLOAT start_x = pCoords->GetNumber(0); FX_FLOAT start_y = pCoords->GetNumber(1); FX_FLOAT start_r = pCoords->GetNumber(2); FX_FLOAT end_x = pCoords->GetNumber(3); FX_FLOAT end_y = pCoords->GetNumber(4); FX_FLOAT end_r = pCoords->GetNumber(5); CFX_Matrix matrix; matrix.SetReverse(*pObject2Bitmap); FX_FLOAT t_min = 0, t_max = 1.0f; CPDF_Array* pArray = pDict->GetArray("Domain"); if (pArray) { t_min = pArray->GetNumber(0); t_max = pArray->GetNumber(1); } FX_BOOL bStartExtend = FALSE, bEndExtend = FALSE; pArray = pDict->GetArray("Extend"); if (pArray) { bStartExtend = pArray->GetInteger(0); bEndExtend = pArray->GetInteger(1); } int total_results = 0; for (int j = 0; j < nFuncs; j++) { if (pFuncs[j]) { total_results += pFuncs[j]->CountOutputs(); } } if (pCS->CountComponents() > total_results) { total_results = pCS->CountComponents(); } CFX_FixedBufGrow<FX_FLOAT, 16> result_array(total_results); FX_FLOAT* pResults = result_array; FXSYS_memset(pResults, 0, total_results * sizeof(FX_FLOAT)); FX_DWORD rgb_array[SHADING_STEPS]; for (int i = 0; i < SHADING_STEPS; i++) { FX_FLOAT input = (t_max - t_min) * i / SHADING_STEPS + t_min; int offset = 0; for (int j = 0; j < nFuncs; j++) { if (pFuncs[j]) { int nresults; if (pFuncs[j]->Call(&input, 1, pResults + offset, nresults)) { offset += nresults; } } } FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f; pCS->GetRGB(pResults, R, G, B); rgb_array[i] = FXARGB_TODIB(FXARGB_MAKE(alpha, FXSYS_round(R * 255), FXSYS_round(G * 255), FXSYS_round(B * 255))); } FX_FLOAT a = FXSYS_Mul(start_x - end_x, start_x - end_x) + FXSYS_Mul(start_y - end_y, start_y - end_y) - FXSYS_Mul(start_r - end_r, start_r - end_r); int width = pBitmap->GetWidth(); int height = pBitmap->GetHeight(); int pitch = pBitmap->GetPitch(); FX_BOOL bDecreasing = FALSE; if (start_r > end_r) { int length = (int)FXSYS_sqrt((FXSYS_Mul(start_x - end_x, start_x - end_x) + FXSYS_Mul(start_y - end_y, start_y - end_y))); if (length < start_r - end_r) { bDecreasing = TRUE; } } for (int row = 0; row < height; row++) { FX_DWORD* dib_buf = (FX_DWORD*)(pBitmap->GetBuffer() + row * pitch); for (int column = 0; column < width; column++) { FX_FLOAT x = (FX_FLOAT)column, y = (FX_FLOAT)row; matrix.Transform(x, y); FX_FLOAT b = -2 * (FXSYS_Mul(x - start_x, end_x - start_x) + FXSYS_Mul(y - start_y, end_y - start_y) + FXSYS_Mul(start_r, end_r - start_r)); FX_FLOAT c = FXSYS_Mul(x - start_x, x - start_x) + FXSYS_Mul(y - start_y, y - start_y) - FXSYS_Mul(start_r, start_r); FX_FLOAT s; if (a == 0) { s = FXSYS_Div(-c, b); } else { FX_FLOAT b2_4ac = FXSYS_Mul(b, b) - 4 * FXSYS_Mul(a, c); if (b2_4ac < 0) { continue; } FX_FLOAT root = FXSYS_sqrt(b2_4ac); FX_FLOAT s1, s2; if (a > 0) { s1 = FXSYS_Div(-b - root, 2 * a); s2 = FXSYS_Div(-b + root, 2 * a); } else { s2 = FXSYS_Div(-b - root, 2 * a); s1 = FXSYS_Div(-b + root, 2 * a); } if (bDecreasing) { if (s1 >= 0 || bStartExtend) { s = s1; } else { s = s2; } } else { if (s2 <= 1.0f || bEndExtend) { s = s2; } else { s = s1; } } if ((start_r + s * (end_r - start_r)) < 0) { continue; } } int index = (int32_t)(s * (SHADING_STEPS - 1)); if (index < 0) { if (!bStartExtend) { continue; } index = 0; } if (index >= SHADING_STEPS) { if (!bEndExtend) { continue; } index = SHADING_STEPS - 1; } dib_buf[column] = rgb_array[index]; } } }