Esempio n. 1
0
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);
    }
  }
}
Esempio n. 2
0
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];
    }
  }
}