static void DrawFreeGouraudShading(CFX_DIBitmap* pBitmap,
                                   CFX_Matrix* pObject2Bitmap,
                                   CPDF_Stream* pShadingStream,
                                   CPDF_Function** pFuncs,
                                   int nFuncs,
                                   CPDF_ColorSpace* pCS,
                                   int alpha) {
  ASSERT(pBitmap->GetFormat() == FXDIB_Argb);

  CPDF_MeshStream stream;
  if (!stream.Load(pShadingStream, pFuncs, nFuncs, pCS))
    return;

  CPDF_MeshVertex triangle[3];
  FXSYS_memset(triangle, 0, sizeof(triangle));

  while (!stream.m_BitStream.IsEOF()) {
    CPDF_MeshVertex vertex;
    FX_DWORD flag = stream.GetVertex(vertex, pObject2Bitmap);
    if (flag == 0) {
      triangle[0] = vertex;
      for (int j = 1; j < 3; j++) {
        stream.GetVertex(triangle[j], pObject2Bitmap);
      }
    } else {
      if (flag == 1) {
        triangle[0] = triangle[1];
      }
      triangle[1] = triangle[2];
      triangle[2] = vertex;
    }
    DrawGouraud(pBitmap, alpha, triangle);
  }
}
Beispiel #2
0
CFX_FloatRect _GetShadingBBox(CPDF_Stream* pStream, int type, const CFX_AffineMatrix* pMatrix,
                              CPDF_Function** pFuncs, int nFuncs, CPDF_ColorSpace* pCS)
{
    if (pStream == NULL || pStream->GetType() != PDFOBJ_STREAM || pFuncs == NULL || pCS == NULL) {
        return CFX_FloatRect(0, 0, 0, 0);
    }
    CPDF_MeshStream stream;
    if (!stream.Load(pStream, pFuncs, nFuncs, pCS)) {
        return CFX_FloatRect(0, 0, 0, 0);
    }
    CFX_FloatRect rect;
    FX_BOOL bStarted = FALSE;
    FX_BOOL bGouraud = type == 4 || type == 5;
    int full_point_count = type == 7 ? 16 : (type == 6 ? 12 : 1);
    int full_color_count = (type == 6 || type == 7) ? 4 : 1;
    while (!stream.m_BitStream.IsEOF()) {
        FX_DWORD flag;
        if (type != 5) {
            flag = stream.GetFlag();
        }
        int point_count = full_point_count, color_count = full_color_count;
        if (!bGouraud && flag) {
            point_count -= 4;
            color_count -= 2;
        }
        for (int i = 0; i < point_count; i ++) {
            FX_FLOAT x, y;
            stream.GetCoords(x, y);
            if (bStarted) {
                rect.UpdateRect(x, y);
            } else {
                rect.InitRect(x, y);
                bStarted = TRUE;
            }
        }
        stream.m_BitStream.SkipBits(stream.m_nComps * stream.m_nCompBits * color_count);
        if (bGouraud) {
            stream.m_BitStream.ByteAlign();
        }
    }
    rect.Transform(pMatrix);
    return rect;
}
static void DrawLatticeGouraudShading(CFX_DIBitmap* pBitmap,
                                      CFX_Matrix* pObject2Bitmap,
                                      CPDF_Stream* pShadingStream,
                                      CPDF_Function** pFuncs,
                                      int nFuncs,
                                      CPDF_ColorSpace* pCS,
                                      int alpha) {
  ASSERT(pBitmap->GetFormat() == FXDIB_Argb);

  int row_verts = pShadingStream->GetDict()->GetInteger("VerticesPerRow");
  if (row_verts < 2)
    return;

  CPDF_MeshStream stream;
  if (!stream.Load(pShadingStream, pFuncs, nFuncs, pCS))
    return;

  CPDF_MeshVertex* vertex = FX_Alloc2D(CPDF_MeshVertex, row_verts, 2);
  if (!stream.GetVertexRow(vertex, row_verts, pObject2Bitmap)) {
    FX_Free(vertex);
    return;
  }
  int last_index = 0;
  while (1) {
    CPDF_MeshVertex* last_row = vertex + last_index * row_verts;
    CPDF_MeshVertex* this_row = vertex + (1 - last_index) * row_verts;
    if (!stream.GetVertexRow(this_row, row_verts, pObject2Bitmap)) {
      FX_Free(vertex);
      return;
    }
    CPDF_MeshVertex triangle[3];
    for (int i = 1; i < row_verts; i++) {
      triangle[0] = last_row[i];
      triangle[1] = this_row[i - 1];
      triangle[2] = last_row[i - 1];
      DrawGouraud(pBitmap, alpha, triangle);
      triangle[2] = this_row[i];
      DrawGouraud(pBitmap, alpha, triangle);
    }
    last_index = 1 - last_index;
  }
  FX_Free(vertex);
}
static void DrawCoonPatchMeshes(FX_BOOL bTensor,
                                CFX_DIBitmap* pBitmap,
                                CFX_Matrix* pObject2Bitmap,
                                CPDF_Stream* pShadingStream,
                                CPDF_Function** pFuncs,
                                int nFuncs,
                                CPDF_ColorSpace* pCS,
                                int fill_mode,
                                int alpha) {
  ASSERT(pBitmap->GetFormat() == FXDIB_Argb);

  CFX_FxgeDevice device;
  device.Attach(pBitmap);
  CPDF_MeshStream stream;
  if (!stream.Load(pShadingStream, pFuncs, nFuncs, pCS))
    return;
  if (!_CheckCoonTensorPara(stream))
    return;

  CPDF_PatchDrawer patch;
  patch.alpha = alpha;
  patch.pDevice = &device;
  patch.fill_mode = fill_mode;
  patch.path.SetPointCount(13);
  FX_PATHPOINT* pPoints = patch.path.GetPoints();
  pPoints[0].m_Flag = FXPT_MOVETO;
  for (int i = 1; i < 13; i++) {
    pPoints[i].m_Flag = FXPT_BEZIERTO;
  }
  CFX_FloatPoint coords[16];
  for (int i = 0; i < 16; i++) {
    coords[i].Set(0.0f, 0.0f);
  }

  int point_count = bTensor ? 16 : 12;
  while (!stream.m_BitStream.IsEOF()) {
    FX_DWORD flag = stream.GetFlag();
    int iStartPoint = 0, iStartColor = 0, i = 0;
    if (flag) {
      iStartPoint = 4;
      iStartColor = 2;
      CFX_FloatPoint tempCoords[4];
      for (i = 0; i < 4; i++) {
        tempCoords[i] = coords[(flag * 3 + i) % 12];
      }
      FXSYS_memcpy(coords, tempCoords, sizeof(CFX_FloatPoint) * 4);
      Coon_Color tempColors[2];
      tempColors[0] = patch.patch_colors[flag];
      tempColors[1] = patch.patch_colors[(flag + 1) % 4];
      FXSYS_memcpy(patch.patch_colors, tempColors, sizeof(Coon_Color) * 2);
    }
    for (i = iStartPoint; i < point_count; i++) {
      stream.GetCoords(coords[i].x, coords[i].y);
      pObject2Bitmap->Transform(coords[i].x, coords[i].y);
    }
    for (i = iStartColor; i < 4; i++) {
      FX_FLOAT r = 0.0f, g = 0.0f, b = 0.0f;
      stream.GetColor(r, g, b);
      patch.patch_colors[i].comp[0] = (int32_t)(r * 255);
      patch.patch_colors[i].comp[1] = (int32_t)(g * 255);
      patch.patch_colors[i].comp[2] = (int32_t)(b * 255);
    }
    CFX_FloatRect bbox = CFX_FloatRect::GetBBox(coords, point_count);
    if (bbox.right <= 0 || bbox.left >= (FX_FLOAT)pBitmap->GetWidth() ||
        bbox.top <= 0 || bbox.bottom >= (FX_FLOAT)pBitmap->GetHeight()) {
      continue;
    }
    Coon_Bezier C1, C2, D1, D2;
    C1.FromPoints(coords[0].x, coords[0].y, coords[11].x, coords[11].y,
                  coords[10].x, coords[10].y, coords[9].x, coords[9].y);
    C2.FromPoints(coords[3].x, coords[3].y, coords[4].x, coords[4].y,
                  coords[5].x, coords[5].y, coords[6].x, coords[6].y);
    D1.FromPoints(coords[0].x, coords[0].y, coords[1].x, coords[1].y,
                  coords[2].x, coords[2].y, coords[3].x, coords[3].y);
    D2.FromPoints(coords[9].x, coords[9].y, coords[8].x, coords[8].y,
                  coords[7].x, coords[7].y, coords[6].x, coords[6].y);
    patch.Draw(1, 1, 0, 0, C1, C2, D1, D2);
  }
}