void CXFA_FFPushButton::OnDrawWidget(CFX_Graphics* pGraphics, const CFX_Matrix* pMatrix) { if (m_pNormalWidget->GetStylesEx() & XFA_FWL_PSBSTYLEEXT_HiliteInverted) { if ((m_pNormalWidget->GetStates() & FWL_STATE_PSB_Pressed) && (m_pNormalWidget->GetStates() & FWL_STATE_PSB_Hovered)) { CFX_RectF rtFill; m_pNormalWidget->GetWidgetRect(rtFill); rtFill.left = rtFill.top = 0; FX_FLOAT fLineWith = GetLineWidth(); rtFill.Deflate(fLineWith, fLineWith); CFX_Color cr(FXARGB_MAKE(128, 128, 255, 255)); pGraphics->SetFillColor(&cr); CFX_Path path; path.Create(); path.AddRectangle(rtFill.left, rtFill.top, rtFill.width, rtFill.height); pGraphics->FillPath(&path, FXFILL_WINDING, (CFX_Matrix*)pMatrix); } } else if (m_pNormalWidget->GetStylesEx() & XFA_FWL_PSBSTYLEEXT_HiliteOutLine) { if ((m_pNormalWidget->GetStates() & FWL_STATE_PSB_Pressed) && (m_pNormalWidget->GetStates() & FWL_STATE_PSB_Hovered)) { FX_FLOAT fLineWidth = GetLineWidth(); CFX_Color cr(FXARGB_MAKE(255, 128, 255, 255)); pGraphics->SetStrokeColor(&cr); pGraphics->SetLineWidth(fLineWidth); CFX_Path path; path.Create(); CFX_RectF rect; m_pNormalWidget->GetWidgetRect(rect); path.AddRectangle(0, 0, rect.width, rect.height); pGraphics->StrokePath(&path, (CFX_Matrix*)pMatrix); } } }
DLLEXPORT void STDCALL FPDFBitmap_FillRect(FPDF_BITMAP bitmap, int left, int top, int width, int height, int red, int green, int blue, int alpha) { if (bitmap == NULL) return; #ifdef _SKIA_SUPPORT_ CFX_SkiaDevice device; #else CFX_FxgeDevice device; #endif device.Attach((CFX_DIBitmap*)bitmap); if (!((CFX_DIBitmap*)bitmap)->HasAlpha()) alpha = 255; FX_RECT rect(left, top, left+width, top+height); device.FillRect(&rect, FXARGB_MAKE(alpha, red, green, blue)); }
void Draw(int x_scale, int y_scale, int left, int bottom, Coon_Bezier C1, Coon_Bezier C2, Coon_Bezier D1, Coon_Bezier D2) { FX_BOOL bSmall = C1.Distance() < 2 && C2.Distance() < 2 && D1.Distance() < 2 && D2.Distance() < 2; Coon_Color div_colors[4]; int d_bottom, d_left, d_top, d_right; div_colors[0].BiInterpol(patch_colors, left, bottom, x_scale, y_scale); if (!bSmall) { div_colors[1].BiInterpol(patch_colors, left, bottom + 1, x_scale, y_scale); div_colors[2].BiInterpol(patch_colors, left + 1, bottom + 1, x_scale, y_scale); div_colors[3].BiInterpol(patch_colors, left + 1, bottom, x_scale, y_scale); d_bottom = div_colors[3].Distance(div_colors[0]); d_left = div_colors[1].Distance(div_colors[0]); d_top = div_colors[1].Distance(div_colors[2]); d_right = div_colors[2].Distance(div_colors[3]); } #define COONCOLOR_THRESHOLD 4 if (bSmall || (d_bottom < COONCOLOR_THRESHOLD && d_left < COONCOLOR_THRESHOLD && d_top < COONCOLOR_THRESHOLD && d_right < COONCOLOR_THRESHOLD)) { FX_PATHPOINT* pPoints = path.GetPoints(); C1.GetPoints(pPoints); D2.GetPoints(pPoints + 3); C2.GetPointsReverse(pPoints + 6); D1.GetPointsReverse(pPoints + 9); int fillFlags = FXFILL_WINDING | FXFILL_FULLCOVER; if (fill_mode & RENDER_NOPATHSMOOTH) { fillFlags |= FXFILL_NOPATHSMOOTH; } pDevice->DrawPath( &path, NULL, NULL, FXARGB_MAKE(alpha, div_colors[0].comp[0], div_colors[0].comp[1], div_colors[0].comp[2]), 0, fillFlags); } else { if (d_bottom < COONCOLOR_THRESHOLD && d_top < COONCOLOR_THRESHOLD) { Coon_Bezier m1; m1.BezierInterpol(D1, D2, C1, C2); y_scale *= 2; bottom *= 2; Draw(x_scale, y_scale, left, bottom, C1, m1, D1.first_half(), D2.first_half()); Draw(x_scale, y_scale, left, bottom + 1, m1, C2, D1.second_half(), D2.second_half()); } else if (d_left < COONCOLOR_THRESHOLD && d_right < COONCOLOR_THRESHOLD) { Coon_Bezier m2; m2.BezierInterpol(C1, C2, D1, D2); x_scale *= 2; left *= 2; Draw(x_scale, y_scale, left, bottom, C1.first_half(), C2.first_half(), D1, m2); Draw(x_scale, y_scale, left + 1, bottom, C1.second_half(), C2.second_half(), m2, D2); } else { Coon_Bezier m1, m2; m1.BezierInterpol(D1, D2, C1, C2); m2.BezierInterpol(C1, C2, D1, D2); Coon_Bezier m1f = m1.first_half(); Coon_Bezier m1s = m1.second_half(); Coon_Bezier m2f = m2.first_half(); Coon_Bezier m2s = m2.second_half(); x_scale *= 2; y_scale *= 2; left *= 2; bottom *= 2; Draw(x_scale, y_scale, left, bottom, C1.first_half(), m1f, D1.first_half(), m2f); Draw(x_scale, y_scale, left, bottom + 1, m1f, C2.first_half(), D1.second_half(), m2s); Draw(x_scale, y_scale, left + 1, bottom, C1.second_half(), m1s, m2f, D2.first_half()); Draw(x_scale, y_scale, left + 1, bottom + 1, m1s, C2.second_half(), m2s, D2.second_half()); } } }
static void DrawGouraud(CFX_DIBitmap* pBitmap, int alpha, CPDF_MeshVertex triangle[3]) { FX_FLOAT min_y = triangle[0].y, max_y = triangle[0].y; for (int i = 1; i < 3; i++) { if (min_y > triangle[i].y) { min_y = triangle[i].y; } if (max_y < triangle[i].y) { max_y = triangle[i].y; } } if (min_y == max_y) { return; } int min_yi = (int)FXSYS_floor(min_y), max_yi = (int)FXSYS_ceil(max_y); if (min_yi < 0) { min_yi = 0; } if (max_yi >= pBitmap->GetHeight()) { max_yi = pBitmap->GetHeight() - 1; } for (int y = min_yi; y <= max_yi; y++) { int nIntersects = 0; FX_FLOAT inter_x[3], r[3], g[3], b[3]; for (int i = 0; i < 3; i++) { CPDF_MeshVertex& vertex1 = triangle[i]; CPDF_MeshVertex& vertex2 = triangle[(i + 1) % 3]; FX_BOOL bIntersect = _GetScanlineIntersect( y, vertex1.x, vertex1.y, vertex2.x, vertex2.y, inter_x[nIntersects]); if (!bIntersect) { continue; } r[nIntersects] = vertex1.r + FXSYS_MulDiv(vertex2.r - vertex1.r, y - vertex1.y, vertex2.y - vertex1.y); g[nIntersects] = vertex1.g + FXSYS_MulDiv(vertex2.g - vertex1.g, y - vertex1.y, vertex2.y - vertex1.y); b[nIntersects] = vertex1.b + FXSYS_MulDiv(vertex2.b - vertex1.b, y - vertex1.y, vertex2.y - vertex1.y); nIntersects++; } if (nIntersects != 2) { continue; } int min_x, max_x, start_index, end_index; if (inter_x[0] < inter_x[1]) { min_x = (int)FXSYS_floor(inter_x[0]); max_x = (int)FXSYS_ceil(inter_x[1]); start_index = 0; end_index = 1; } else { min_x = (int)FXSYS_floor(inter_x[1]); max_x = (int)FXSYS_ceil(inter_x[0]); start_index = 1; end_index = 0; } int start_x = min_x, end_x = max_x; if (start_x < 0) { start_x = 0; } if (end_x > pBitmap->GetWidth()) { end_x = pBitmap->GetWidth(); } uint8_t* dib_buf = pBitmap->GetBuffer() + y * pBitmap->GetPitch() + start_x * 4; FX_FLOAT r_unit = (r[end_index] - r[start_index]) / (max_x - min_x); FX_FLOAT g_unit = (g[end_index] - g[start_index]) / (max_x - min_x); FX_FLOAT b_unit = (b[end_index] - b[start_index]) / (max_x - min_x); FX_FLOAT R = r[start_index] + (start_x - min_x) * r_unit; FX_FLOAT G = g[start_index] + (start_x - min_x) * g_unit; FX_FLOAT B = b[start_index] + (start_x - min_x) * b_unit; for (int x = start_x; x < end_x; x++) { R += r_unit; G += g_unit; B += b_unit; FXARGB_SETDIB(dib_buf, FXARGB_MAKE(alpha, (int32_t)(R * 255), (int32_t)(G * 255), (int32_t)(B * 255))); dib_buf += 4; } } }
static void DrawFuncShading(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* pDomain = pDict->GetArray("Domain"); FX_FLOAT xmin = 0, ymin = 0, xmax = 1.0f, ymax = 1.0f; if (pDomain) { xmin = pDomain->GetNumber(0); xmax = pDomain->GetNumber(1); ymin = pDomain->GetNumber(2); ymax = pDomain->GetNumber(3); } CFX_Matrix mtDomain2Target = pDict->GetMatrix("Matrix"); CFX_Matrix matrix, reverse_matrix; matrix.SetReverse(*pObject2Bitmap); reverse_matrix.SetReverse(mtDomain2Target); matrix.Concat(reverse_matrix); int width = pBitmap->GetWidth(); int height = pBitmap->GetHeight(); int pitch = pBitmap->GetPitch(); 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)); 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); if (x < xmin || x > xmax || y < ymin || y > ymax) { continue; } FX_FLOAT input[2]; int offset = 0; input[0] = x; input[1] = y; for (int j = 0; j < nFuncs; j++) { if (pFuncs[j]) { int nresults; if (pFuncs[j]->Call(input, 2, pResults + offset, nresults)) { offset += nresults; } } } FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f; pCS->GetRGB(pResults, R, G, B); dib_buf[column] = FXARGB_TODIB(FXARGB_MAKE( alpha, (int32_t)(R * 255), (int32_t)(G * 255), (int32_t)(B * 255))); } } }
static void DrawAxialShading(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 end_x = pCoords->GetNumber(2); FX_FLOAT end_y = pCoords->GetNumber(3); 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 width = pBitmap->GetWidth(); int height = pBitmap->GetHeight(); FX_FLOAT x_span = end_x - start_x; FX_FLOAT y_span = end_y - start_y; FX_FLOAT axis_len_square = FXSYS_Mul(x_span, x_span) + FXSYS_Mul(y_span, y_span); CFX_Matrix matrix; matrix.SetReverse(*pObject2Bitmap); 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 = 0; 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))); } int pitch = pBitmap->GetPitch(); 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 scale = FXSYS_Div( FXSYS_Mul(x - start_x, x_span) + FXSYS_Mul(y - start_y, y_span), axis_len_square); int index = (int32_t)(scale * (SHADING_STEPS - 1)); if (index < 0) { if (!bStartExtend) { continue; } index = 0; } else if (index >= SHADING_STEPS) { if (!bEndExtend) { continue; } index = SHADING_STEPS - 1; } dib_buf[column] = rgb_array[index]; } } }
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]; } } }