Exemple #1
0
FX_BOOL CFX_GEFont::GetCharBBox(FX_WCHAR wUnicode,
                                CFX_Rect& bbox,
                                FX_BOOL bRecursive,
                                FX_BOOL bCharCode) {
  FXSYS_assert(m_pRectArray != NULL);
  FXSYS_assert(m_pBBoxMap != NULL);
  void* pRect = NULL;
  if (!m_pBBoxMap->Lookup((void*)(uintptr_t)wUnicode, pRect)) {
    IFX_Font* pFont = NULL;
    int32_t iGlyph = GetGlyphIndex(wUnicode, TRUE, &pFont, bCharCode);
    if (iGlyph != 0xFFFF && pFont != NULL) {
      if (pFont == (IFX_Font*)this) {
        FX_RECT rtBBox;
        if (m_pFont->GetGlyphBBox(iGlyph, rtBBox)) {
          Lock();
          CFX_Rect rt;
          rt.Set(rtBBox.left, rtBBox.top, rtBBox.Width(), rtBBox.Height());
          int32_t index = m_pRectArray->Add(rt);
          pRect = m_pRectArray->GetPtrAt(index);
          m_pBBoxMap->SetAt((void*)(uintptr_t)wUnicode, pRect);
          Unlock();
        }
      } else if (((CFX_GEFont*)pFont)
                     ->GetCharBBox(wUnicode, bbox, FALSE, bCharCode)) {
        return TRUE;
      }
    }
  }
  if (pRect == NULL) {
    return FALSE;
  }
  bbox = *(FX_LPCRECT)pRect;
  return TRUE;
}
FX_BOOL CFGAS_GEFont::GetCharBBoxInternal(FX_WCHAR wUnicode,
                                          CFX_Rect& bbox,
                                          FX_BOOL bRecursive,
                                          FX_BOOL bCharCode) {
  ASSERT(m_pRectArray);
  ASSERT(m_pBBoxMap);
  void* pRect = nullptr;
  if (!m_pBBoxMap->Lookup((void*)(uintptr_t)wUnicode, pRect)) {
    CFGAS_GEFont* pFont = nullptr;
    int32_t iGlyph = GetGlyphIndex(wUnicode, TRUE, &pFont, bCharCode);
    if (iGlyph != 0xFFFF && pFont) {
      if (pFont == this) {
        FX_RECT rtBBox;
        if (m_pFont->GetGlyphBBox(iGlyph, rtBBox)) {
          CFX_Rect rt;
          rt.Set(rtBBox.left, rtBBox.top, rtBBox.Width(), rtBBox.Height());
          int32_t index = m_pRectArray->Add(rt);
          pRect = m_pRectArray->GetPtrAt(index);
          m_pBBoxMap->SetAt((void*)(uintptr_t)wUnicode, pRect);
        }
      } else if (pFont->GetCharBBoxInternal(wUnicode, bbox, FALSE, bCharCode)) {
        return TRUE;
      }
    }
  }
  if (!pRect)
    return FALSE;

  bbox = *static_cast<const CFX_Rect*>(pRect);
  return TRUE;
}
FX_RECT CFX_FloatRect::GetClosestRect() const {
    CFX_FloatRect rect1 = *this;
    FX_RECT rect;
    _MatchFloatRange(rect1.left, rect1.right, rect.left, rect.right);
    _MatchFloatRange(rect1.bottom, rect1.top, rect.top, rect.bottom);
    rect.Normalize();
    return rect;
}
void FX_RECT::Union(const FX_RECT& other_rect) {
    Normalize();
    FX_RECT other = other_rect;
    other.Normalize();
    left = left < other.left ? left : other.left;
    right = right > other.right ? right : other.right;
    bottom = bottom > other.bottom ? bottom : other.bottom;
    top = top < other.top ? top : other.top;
}
FX_RECT CFX_FloatRect::GetInnerRect() const {
    CFX_FloatRect rect1 = *this;
    FX_RECT rect;
    rect.left = (int)FXSYS_ceil(rect1.left);
    rect.right = (int)FXSYS_floor(rect1.right);
    rect.top = (int)FXSYS_ceil(rect1.bottom);
    rect.bottom = (int)FXSYS_floor(rect1.top);
    rect.Normalize();
    return rect;
}
FX_BOOL CPDF_RenderStatus::ProcessShading(CPDF_ShadingObject* pShadingObj,
                                          const CFX_Matrix* pObj2Device) {
  FX_RECT rect = pShadingObj->GetBBox(pObj2Device);
  FX_RECT clip_box = m_pDevice->GetClipBox();
  rect.Intersect(clip_box);
  if (rect.IsEmpty()) {
    return TRUE;
  }
  CFX_Matrix matrix = pShadingObj->m_Matrix;
  matrix.Concat(*pObj2Device);
  DrawShading(pShadingObj->m_pShading, &matrix, rect,
              pShadingObj->m_GeneralState.GetAlpha(FALSE),
              m_Options.m_ColorMode == RENDER_COLOR_ALPHA);
  return TRUE;
}
Exemple #7
0
FX_FLOAT CPWL_Edit::GetCharArrayAutoFontSize(CPDF_Font* pFont,
                                             const CPDF_Rect& rcPlate,
                                             int32_t nCharArray) {
  if (pFont && !pFont->IsStandardFont()) {
    FX_RECT rcBBox;
    pFont->GetFontBBox(rcBBox);

    CPDF_Rect rcCell = rcPlate;
    FX_FLOAT xdiv = rcCell.Width() / nCharArray * 1000.0f / rcBBox.Width();
    FX_FLOAT ydiv = -rcCell.Height() * 1000.0f / rcBBox.Height();

    return xdiv < ydiv ? xdiv : ydiv;
  }

  return 0.0f;
}
Exemple #8
0
FX_BOOL CFFL_FormFiller::OnLButtonDown(CPDFSDK_PageView* pPageView,
                                       CPDFSDK_Annot* pAnnot,
                                       FX_UINT nFlags,
                                       const CPDF_Point& point) {
  if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, TRUE)) {
    m_bValid = TRUE;
    FX_RECT rect = GetViewBBox(pPageView, pAnnot);
    InvalidateRect(rect.left, rect.top, rect.right, rect.bottom);

    if (!rect.Contains((int)point.x, (int)point.y))
      return FALSE;

    return pWnd->OnLButtonDown(WndtoPWL(pPageView, point), nFlags);
  }

  return FALSE;
}
Exemple #9
0
FX_FLOAT CPDF_TextObject::GetSpaceCharWidth() const {
  CPDF_Font* pFont = m_TextState.GetFont();
  FX_DWORD charCode = m_TextState.GetFont()->CharCodeFromUnicode(32);
  if (charCode != (FX_DWORD)-1) {
    return GetCharWidth(charCode);
  }
  FX_FLOAT fontSize = m_TextState.GetFontSize() / 4000.0f;
  FX_BOOL bVertWriting = FALSE;
  CPDF_CIDFont* pCIDFont = pFont->GetCIDFont();
  if (pCIDFont) {
    bVertWriting = pCIDFont->IsVertWriting();
  }
  FX_RECT fontRect;
  pFont->GetFontBBox(fontRect);
  fontSize *=
      bVertWriting ? (FX_FLOAT)fontRect.Height() : (FX_FLOAT)fontRect.Width();
  return fontSize;
}
Exemple #10
0
CFX_DIBitmap* CPDF_RenderStatus::GetBackdrop(const CPDF_PageObject* pObj,
                                             const FX_RECT& rect,
                                             int& left,
                                             int& top,
                                             FX_BOOL bBackAlphaRequired) {
  FX_RECT bbox = rect;
  bbox.Intersect(m_pDevice->GetClipBox());
  left = bbox.left;
  top = bbox.top;
  CFX_Matrix deviceCTM = m_pDevice->GetCTM();
  FX_FLOAT scaleX = FXSYS_fabs(deviceCTM.a);
  FX_FLOAT scaleY = FXSYS_fabs(deviceCTM.d);
  int width = FXSYS_round(bbox.Width() * scaleX);
  int height = FXSYS_round(bbox.Height() * scaleY);
  std::unique_ptr<CFX_DIBitmap> pBackdrop(new CFX_DIBitmap);
  if (bBackAlphaRequired && !m_bDropObjects)
    pBackdrop->Create(width, height, FXDIB_Argb);
  else
    m_pDevice->CreateCompatibleBitmap(pBackdrop.get(), width, height);

  if (!pBackdrop->GetBuffer())
    return nullptr;

  FX_BOOL bNeedDraw;
  if (pBackdrop->HasAlpha())
    bNeedDraw = !(m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT);
  else
    bNeedDraw = !(m_pDevice->GetRenderCaps() & FXRC_GET_BITS);

  if (!bNeedDraw) {
    m_pDevice->GetDIBits(pBackdrop.get(), left, top);
    return pBackdrop.release();
  }

  CFX_Matrix FinalMatrix = m_DeviceMatrix;
  FinalMatrix.TranslateI(-left, -top);
  FinalMatrix.Scale(scaleX, scaleY);
  pBackdrop->Clear(pBackdrop->HasAlpha() ? 0 : 0xffffffff);
  CFX_FxgeDevice device;
  device.Attach(pBackdrop.get(), false, nullptr, false);
  m_pContext->Render(&device, pObj, &m_Options, &FinalMatrix);
  return pBackdrop.release();
}
FX_RECT _FXDIB_SwapClipBox(FX_RECT& clip, int width, int height, FX_BOOL bFlipX, FX_BOOL bFlipY)
{
    FX_RECT rect;
    if (bFlipY) {
        rect.left = height - clip.top;
        rect.right = height - clip.bottom;
    } else {
        rect.left = clip.top;
        rect.right = clip.bottom;
    }
    if (bFlipX) {
        rect.top = width - clip.left;
        rect.bottom = width - clip.right;
    } else {
        rect.top = clip.left;
        rect.bottom = clip.right;
    }
    rect.Normalize();
    return rect;
}
void CPDF_ImageRenderer::CalculateDrawImage(CFX_FxgeDevice* pBitmapDevice1,
                                            CFX_FxgeDevice* pBitmapDevice2,
                                            const CFX_DIBSource* pDIBSource,
                                            CFX_Matrix* pNewMatrix,
                                            const FX_RECT& rect) const {
  CPDF_RenderStatus bitmap_render;
  bitmap_render.Initialize(m_pRenderStatus->m_pContext, pBitmapDevice2, nullptr,
                           nullptr, nullptr, nullptr, nullptr, 0,
                           m_pRenderStatus->m_bDropObjects, nullptr, true);
  CPDF_ImageRenderer image_render;
  if (image_render.Start(&bitmap_render, pDIBSource, 0xffffffff, 255,
                         pNewMatrix, m_Flags, true, FXDIB_BLEND_NORMAL)) {
    image_render.Continue(nullptr);
  }
  if (m_Loader.m_MatteColor == 0xffffffff)
    return;
  int matte_r = FXARGB_R(m_Loader.m_MatteColor);
  int matte_g = FXARGB_G(m_Loader.m_MatteColor);
  int matte_b = FXARGB_B(m_Loader.m_MatteColor);
  for (int row = 0; row < rect.Height(); row++) {
    uint8_t* dest_scan =
        const_cast<uint8_t*>(pBitmapDevice1->GetBitmap()->GetScanline(row));
    const uint8_t* mask_scan = pBitmapDevice2->GetBitmap()->GetScanline(row);
    for (int col = 0; col < rect.Width(); col++) {
      int alpha = *mask_scan++;
      if (!alpha) {
        dest_scan += 4;
        continue;
      }
      int orig = (*dest_scan - matte_b) * 255 / alpha + matte_b;
      *dest_scan++ = std::min(std::max(orig, 0), 255);
      orig = (*dest_scan - matte_g) * 255 / alpha + matte_g;
      *dest_scan++ = std::min(std::max(orig, 0), 255);
      orig = (*dest_scan - matte_r) * 255 / alpha + matte_r;
      *dest_scan++ = std::min(std::max(orig, 0), 255);
      dest_scan++;
    }
  }
}
Exemple #13
0
STDMETHODIMP CDwGdiTextRenderer::DrawGlyphRun(
    const FX_RECT& text_bbox,
    __in_opt CFX_ClipRgn* pClipRgn,
    __in_opt DWRITE_MATRIX const* pMatrix,
    FLOAT baselineOriginX,
    FLOAT baselineOriginY,
    DWRITE_MEASURING_MODE measuringMode,
    __in DWRITE_GLYPH_RUN const* glyphRun,
    const COLORREF& textColor) {
  HRESULT hr = S_OK;
  if (pMatrix) {
    hr = pRenderTarget_->SetCurrentTransform(pMatrix);
    if (FAILED(hr)) {
      return hr;
    }
  }
  HDC hDC = pRenderTarget_->GetMemoryDC();
  HBITMAP hBitmap = (HBITMAP)::GetCurrentObject(hDC, OBJ_BITMAP);
  BITMAP bitmap;
  GetObject(hBitmap, sizeof bitmap, &bitmap);
  CFX_DIBitmap dib;
  dib.Create(bitmap.bmWidth, bitmap.bmHeight,
             bitmap.bmBitsPixel == 24 ? FXDIB_Rgb : FXDIB_Rgb32,
             (uint8_t*)bitmap.bmBits);
  dib.CompositeBitmap(text_bbox.left, text_bbox.top, text_bbox.Width(),
                      text_bbox.Height(), pBitmap_, text_bbox.left,
                      text_bbox.top, FXDIB_BLEND_NORMAL, nullptr);
  hr = pRenderTarget_->DrawGlyphRun(baselineOriginX, baselineOriginY,
                                    measuringMode, glyphRun, pRenderingParams_,
                                    textColor);
  if (FAILED(hr)) {
    return hr;
  }
  pBitmap_->CompositeBitmap(text_bbox.left, text_bbox.top, text_bbox.Width(),
                            text_bbox.Height(), &dib, text_bbox.left,
                            text_bbox.top, FXDIB_BLEND_NORMAL, pClipRgn);
  return hr;
}
Exemple #14
0
bool CFFL_InteractiveFormFiller::OnLButtonUp(CPDFSDK_PageView* pPageView,
                                             CPDFSDK_Annot::ObservedPtr* pAnnot,
                                             uint32_t nFlags,
                                             const CFX_PointF& point) {
  ASSERT((*pAnnot)->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET);
  CPDFSDK_Widget* pWidget = ToCPDFSDKWidget(pAnnot->Get());

  bool bSetFocus;
  switch (pWidget->GetFieldType()) {
    case FormFieldType::kPushButton:
    case FormFieldType::kCheckBox:
    case FormFieldType::kRadioButton: {
      FX_RECT bbox = GetViewBBox(pPageView, pAnnot->Get());
      bSetFocus =
          bbox.Contains(static_cast<int>(point.x), static_cast<int>(point.y));
      break;
    }
    default:
      bSetFocus = true;
      break;
  }
  if (bSetFocus)
    m_pFormFillEnv->SetFocusAnnot(pAnnot);

  CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot->Get(), false);
  bool bRet = pFormFiller &&
              pFormFiller->OnLButtonUp(pPageView, pAnnot->Get(), nFlags, point);
  if (m_pFormFillEnv->GetFocusAnnot() != pAnnot->Get())
    return bRet;
  if (OnButtonUp(pAnnot, pPageView, nFlags) || !pAnnot)
    return true;
#ifdef PDF_ENABLE_XFA
  if (OnClick(pAnnot, pPageView, nFlags) || !pAnnot)
    return true;
#endif  // PDF_ENABLE_XFA
  return bRet;
}
bool CPDF_ImageRenderer::DrawMaskedImage() {
  if (NotDrawing()) {
    m_Result = false;
    return false;
  }

  FX_RECT rect = GetDrawRect();
  if (rect.IsEmpty())
    return false;

  CFX_Matrix new_matrix = GetDrawMatrix(rect);
  CFX_FxgeDevice bitmap_device1;
  if (!bitmap_device1.Create(rect.Width(), rect.Height(), FXDIB_Rgb32, nullptr))
    return true;

#if defined _SKIA_SUPPORT_
  bitmap_device1.Clear(0xffffff);
#else
  bitmap_device1.GetBitmap()->Clear(0xffffff);
#endif
  CPDF_RenderStatus bitmap_render;
  bitmap_render.Initialize(m_pRenderStatus->m_pContext, &bitmap_device1,
                           nullptr, nullptr, nullptr, nullptr, nullptr, 0,
                           m_pRenderStatus->m_bDropObjects, nullptr, true);
  CPDF_ImageRenderer image_render;
  if (image_render.Start(&bitmap_render, m_pDIBSource, 0, 255, &new_matrix,
                         m_Flags, true, FXDIB_BLEND_NORMAL)) {
    image_render.Continue(nullptr);
  }
  CFX_FxgeDevice bitmap_device2;
  if (!bitmap_device2.Create(rect.Width(), rect.Height(), FXDIB_8bppRgb,
                             nullptr))
    return true;

#if defined _SKIA_SUPPORT_
  bitmap_device2.Clear(0);
#else
  bitmap_device2.GetBitmap()->Clear(0);
#endif
  CalculateDrawImage(&bitmap_device1, &bitmap_device2, m_Loader.m_pMask,
                     &new_matrix, rect);
#ifdef _SKIA_SUPPORT_
  m_pRenderStatus->m_pDevice->SetBitsWithMask(
      bitmap_device1.GetBitmap(), bitmap_device2.GetBitmap(), rect.left,
      rect.top, m_BitmapAlpha, m_BlendType);
#else
  bitmap_device2.GetBitmap()->ConvertFormat(FXDIB_8bppMask);
  bitmap_device1.GetBitmap()->MultiplyAlpha(bitmap_device2.GetBitmap());
  if (m_BitmapAlpha < 255)
    bitmap_device1.GetBitmap()->MultiplyAlpha(m_BitmapAlpha);
  m_pRenderStatus->m_pDevice->SetDIBitsWithBlend(
      bitmap_device1.GetBitmap(), rect.left, rect.top, m_BlendType);
#endif  //  _SKIA_SUPPORT_
  return false;
}
bool CPDF_ImageRenderer::DrawPatternImage(const CFX_Matrix* pObj2Device) {
  if (NotDrawing()) {
    m_Result = false;
    return false;
  }

  FX_RECT rect = GetDrawRect();
  if (rect.IsEmpty())
    return false;

  CFX_Matrix new_matrix = GetDrawMatrix(rect);
  CFX_FxgeDevice bitmap_device1;
  if (!bitmap_device1.Create(rect.Width(), rect.Height(), FXDIB_Rgb32, nullptr))
    return true;

  bitmap_device1.GetBitmap()->Clear(0xffffff);
  CPDF_RenderStatus bitmap_render;
  bitmap_render.Initialize(m_pRenderStatus->m_pContext, &bitmap_device1,
                           nullptr, nullptr, nullptr, nullptr,
                           &m_pRenderStatus->m_Options, 0,
                           m_pRenderStatus->m_bDropObjects, nullptr, true);
  CFX_Matrix patternDevice = *pObj2Device;
  patternDevice.Translate((FX_FLOAT)-rect.left, (FX_FLOAT)-rect.top);
  if (CPDF_TilingPattern* pTilingPattern = m_pPattern->AsTilingPattern()) {
    bitmap_render.DrawTilingPattern(pTilingPattern, m_pImageObject,
                                    &patternDevice, false);
  } else if (CPDF_ShadingPattern* pShadingPattern =
                 m_pPattern->AsShadingPattern()) {
    bitmap_render.DrawShadingPattern(pShadingPattern, m_pImageObject,
                                     &patternDevice, false);
  }

  CFX_FxgeDevice bitmap_device2;
  if (!bitmap_device2.Create(rect.Width(), rect.Height(), FXDIB_8bppRgb,
                             nullptr)) {
    return true;
  }
  bitmap_device2.GetBitmap()->Clear(0);
  CalculateDrawImage(&bitmap_device1, &bitmap_device2, m_pDIBSource,
                     &new_matrix, rect);
  bitmap_device2.GetBitmap()->ConvertFormat(FXDIB_8bppMask);
  bitmap_device1.GetBitmap()->MultiplyAlpha(bitmap_device2.GetBitmap());
  bitmap_device1.GetBitmap()->MultiplyAlpha(255);
  m_pRenderStatus->m_pDevice->SetDIBitsWithBlend(
      bitmap_device1.GetBitmap(), rect.left, rect.top, m_BlendType);
  return false;
}
Exemple #17
0
FX_BOOL CPDF_RenderStatus::GetObjectClippedRect(const CPDF_PageObject* pObj,
                                                const CFX_Matrix* pObj2Device,
                                                FX_BOOL bLogical,
                                                FX_RECT& rect) const {
  rect = pObj->GetBBox(pObj2Device);
  FX_RECT rtClip = m_pDevice->GetClipBox();
  if (!bLogical) {
    CFX_Matrix dCTM = m_pDevice->GetCTM();
    FX_FLOAT a = FXSYS_fabs(dCTM.a);
    FX_FLOAT d = FXSYS_fabs(dCTM.d);
    if (a != 1.0f || d != 1.0f) {
      rect.right = rect.left + (int32_t)FXSYS_ceil((FX_FLOAT)rect.Width() * a);
      rect.bottom = rect.top + (int32_t)FXSYS_ceil((FX_FLOAT)rect.Height() * d);
      rtClip.right =
          rtClip.left + (int32_t)FXSYS_ceil((FX_FLOAT)rtClip.Width() * a);
      rtClip.bottom =
          rtClip.top + (int32_t)FXSYS_ceil((FX_FLOAT)rtClip.Height() * d);
    }
  }
  rect.Intersect(rtClip);
  return rect.IsEmpty();
}
CStretchEngine::CStretchEngine(IFX_ScanlineComposer* pDestBitmap, FXDIB_Format dest_format,
                               int dest_width, int dest_height, const FX_RECT& clip_rect,
                               const CFX_DIBSource* pSrcBitmap, int flags)
{
    m_State = 0;
    m_DestFormat = dest_format;
    m_DestBpp = dest_format & 0xff;
    m_SrcBpp = pSrcBitmap->GetFormat() & 0xff;
    m_bHasAlpha = pSrcBitmap->GetFormat() & 0x200;
    m_pSrcPalette = pSrcBitmap->GetPalette();
    m_pDestBitmap = pDestBitmap;
    m_DestWidth = dest_width;
    m_DestHeight = dest_height;
    m_pInterBuf = NULL;
    m_pExtraAlphaBuf = NULL;
    m_pDestMaskScanline = NULL;
    m_DestClip = clip_rect;
    FX_DWORD size = clip_rect.Width();
    if (size && m_DestBpp > (int)(INT_MAX / size)) {
        return;
    }
    size *= m_DestBpp;
    if (size > INT_MAX - 31) {
        return;
    }
    size += 31;
    size = size / 32 * 4;
    m_pDestScanline = FX_AllocNL(FX_BYTE, size);
    if (m_pDestScanline == NULL) {
        return;
    }
    if (dest_format == FXDIB_Rgb32) {
        FXSYS_memset8(m_pDestScanline, 255, size);
    }
    m_InterPitch = (m_DestClip.Width() * m_DestBpp + 31) / 32 * 4;
    m_ExtraMaskPitch = (m_DestClip.Width() * 8 + 31) / 32 * 4;
    m_pInterBuf = NULL;
    m_pSource = pSrcBitmap;
    m_SrcWidth = pSrcBitmap->GetWidth();
    m_SrcHeight = pSrcBitmap->GetHeight();
    m_SrcPitch = (m_SrcWidth * m_SrcBpp + 31) / 32 * 4;
    if ((flags & FXDIB_NOSMOOTH) == 0) {
        FX_BOOL bInterpol = flags & FXDIB_INTERPOL || flags & FXDIB_BICUBIC_INTERPOL;
        if (!bInterpol && FXSYS_abs(dest_width) != 0 && FXSYS_abs(dest_height) < m_SrcWidth * m_SrcHeight * 8 / FXSYS_abs(dest_width)) {
            flags = FXDIB_INTERPOL;
        }
        m_Flags = flags;
    } else {
        m_Flags = FXDIB_NOSMOOTH;
        if (flags & FXDIB_DOWNSAMPLE) {
            m_Flags |= FXDIB_DOWNSAMPLE;
        }
    }
    double scale_x = FXSYS_Div((FX_FLOAT)(m_SrcWidth), (FX_FLOAT)(m_DestWidth));
    double scale_y = FXSYS_Div((FX_FLOAT)(m_SrcHeight), (FX_FLOAT)(m_DestHeight));
    double base_x = m_DestWidth > 0 ? 0.0f : (FX_FLOAT)(m_DestWidth);
    double base_y = m_DestHeight > 0 ? 0.0f : (FX_FLOAT)(m_DestHeight);
    double src_left = FXSYS_Mul(scale_x, (FX_FLOAT)(clip_rect.left) + base_x);
    double src_right = FXSYS_Mul(scale_x, (FX_FLOAT)(clip_rect.right) + base_x);
    double src_top = FXSYS_Mul(scale_y, (FX_FLOAT)(clip_rect.top) + base_y);
    double src_bottom = FXSYS_Mul(scale_y, (FX_FLOAT)(clip_rect.bottom) + base_y);
    if (src_left > src_right) {
        double temp = src_left;
        src_left = src_right;
        src_right = temp;
    }
    if (src_top > src_bottom) {
        double temp = src_top;
        src_top = src_bottom;
        src_bottom = temp;
    }
    m_SrcClip.left = (int)FXSYS_floor((FX_FLOAT)src_left);
    m_SrcClip.right = (int)FXSYS_ceil((FX_FLOAT)src_right);
    m_SrcClip.top = (int)FXSYS_floor((FX_FLOAT)src_top);
    m_SrcClip.bottom = (int)FXSYS_ceil((FX_FLOAT)src_bottom);
    FX_RECT src_rect(0, 0, m_SrcWidth, m_SrcHeight);
    m_SrcClip.Intersect(src_rect);
    if (m_SrcBpp == 1) {
        if (m_DestBpp == 8) {
            m_TransMethod = 1;
        } else {
            m_TransMethod = 2;
        }
    } else if (m_SrcBpp == 8) {
        if (m_DestBpp == 8) {
            if (!m_bHasAlpha) {
                m_TransMethod = 3;
            } else {
                m_TransMethod = 4;
            }
        } else {
            if (!m_bHasAlpha) {
                m_TransMethod = 5;
            } else {
                m_TransMethod = 6;
            }
        }
    } else {
        if (!m_bHasAlpha) {
            m_TransMethod = 7;
        } else {
            m_TransMethod = 8;
        }
    }
}
void CPDF_RenderStatus::DrawShading(CPDF_ShadingPattern* pPattern,
                                    CFX_Matrix* pMatrix,
                                    FX_RECT& clip_rect,
                                    int alpha,
                                    FX_BOOL bAlphaMode) {
  CPDF_Function** pFuncs = pPattern->m_pFunctions;
  int nFuncs = pPattern->m_nFuncs;
  CPDF_Dictionary* pDict = pPattern->m_pShadingObj->GetDict();
  CPDF_ColorSpace* pColorSpace = pPattern->m_pCS;
  if (!pColorSpace) {
    return;
  }
  FX_ARGB background = 0;
  if (!pPattern->m_bShadingObj &&
      pPattern->m_pShadingObj->GetDict()->KeyExist("Background")) {
    CPDF_Array* pBackColor =
        pPattern->m_pShadingObj->GetDict()->GetArray("Background");
    if (pBackColor &&
        pBackColor->GetCount() >= (FX_DWORD)pColorSpace->CountComponents()) {
      CFX_FixedBufGrow<FX_FLOAT, 16> comps(pColorSpace->CountComponents());
      for (int i = 0; i < pColorSpace->CountComponents(); i++) {
        comps[i] = pBackColor->GetNumber(i);
      }
      FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f;
      pColorSpace->GetRGB(comps, R, G, B);
      background = ArgbEncode(255, (int32_t)(R * 255), (int32_t)(G * 255),
                              (int32_t)(B * 255));
    }
  }
  if (pDict->KeyExist("BBox")) {
    CFX_FloatRect rect = pDict->GetRect("BBox");
    rect.Transform(pMatrix);
    clip_rect.Intersect(rect.GetOutterRect());
  }
  CPDF_DeviceBuffer buffer;
  buffer.Initialize(m_pContext, m_pDevice, &clip_rect, m_pCurObj, 150);
  CFX_Matrix FinalMatrix = *pMatrix;
  FinalMatrix.Concat(*buffer.GetMatrix());
  CFX_DIBitmap* pBitmap = buffer.GetBitmap();
  if (!pBitmap->GetBuffer()) {
    return;
  }
  pBitmap->Clear(background);
  int fill_mode = m_Options.m_Flags;
  switch (pPattern->m_ShadingType) {
    case kInvalidShading:
    case kMaxShading:
      return;
    case kFunctionBasedShading:
      DrawFuncShading(pBitmap, &FinalMatrix, pDict, pFuncs, nFuncs, pColorSpace,
                      alpha);
      break;
    case kAxialShading:
      DrawAxialShading(pBitmap, &FinalMatrix, pDict, pFuncs, nFuncs,
                       pColorSpace, alpha);
      break;
    case kRadialShading:
      DrawRadialShading(pBitmap, &FinalMatrix, pDict, pFuncs, nFuncs,
                        pColorSpace, alpha);
      break;
    case kFreeFormGouraudTriangleMeshShading: {
      DrawFreeGouraudShading(pBitmap, &FinalMatrix,
                             ToStream(pPattern->m_pShadingObj), pFuncs, nFuncs,
                             pColorSpace, alpha);
    } break;
    case kLatticeFormGouraudTriangleMeshShading: {
      DrawLatticeGouraudShading(pBitmap, &FinalMatrix,
                                ToStream(pPattern->m_pShadingObj), pFuncs,
                                nFuncs, pColorSpace, alpha);
    } break;
    case kCoonsPatchMeshShading:
    case kTensorProductPatchMeshShading: {
      DrawCoonPatchMeshes(
          pPattern->m_ShadingType == kTensorProductPatchMeshShading, pBitmap,
          &FinalMatrix, ToStream(pPattern->m_pShadingObj), pFuncs, nFuncs,
          pColorSpace, fill_mode, alpha);
    } break;
  }
  if (bAlphaMode) {
    pBitmap->LoadChannel(FXDIB_Red, pBitmap, FXDIB_Alpha);
  }
  if (m_Options.m_ColorMode == RENDER_COLOR_GRAY) {
    pBitmap->ConvertColorScale(m_Options.m_ForeColor, m_Options.m_BackColor);
  }
  buffer.OutputToDevice();
}
Exemple #20
0
FX_BOOL CPDF_RenderStatus::ProcessTransparency(CPDF_PageObject* pPageObj,
                                               const CFX_Matrix* pObj2Device) {
#if defined _SKIA_SUPPORT_
  DebugVerifyDeviceIsPreMultiplied();
#endif
  int blend_type = pPageObj->m_GeneralState.GetBlendType();
  if (blend_type == FXDIB_BLEND_UNSUPPORTED)
    return TRUE;

  CPDF_Dictionary* pSMaskDict =
      ToDictionary(pPageObj->m_GeneralState.GetSoftMask());
  if (pSMaskDict) {
    if (pPageObj->IsImage() &&
        pPageObj->AsImage()->GetImage()->GetDict()->KeyExist("SMask")) {
      pSMaskDict = nullptr;
    }
  }
  CPDF_Dictionary* pFormResource = nullptr;
  FX_FLOAT group_alpha = 1.0f;
  int Transparency = m_Transparency;
  FX_BOOL bGroupTransparent = FALSE;
  if (pPageObj->IsForm()) {
    const CPDF_FormObject* pFormObj = pPageObj->AsForm();
    group_alpha = pFormObj->m_GeneralState.GetFillAlpha();
    Transparency = pFormObj->m_pForm->m_Transparency;
    bGroupTransparent = !!(Transparency & PDFTRANS_ISOLATED);
    if (pFormObj->m_pForm->m_pFormDict) {
      pFormResource = pFormObj->m_pForm->m_pFormDict->GetDictBy("Resources");
    }
  }
  bool bTextClip =
      (pPageObj->m_ClipPath && pPageObj->m_ClipPath.GetTextCount() &&
       m_pDevice->GetDeviceClass() == FXDC_DISPLAY &&
       !(m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_SOFT_CLIP));
  if ((m_Options.m_Flags & RENDER_OVERPRINT) && pPageObj->IsImage() &&
      pPageObj->m_GeneralState.GetFillOP() &&
      pPageObj->m_GeneralState.GetStrokeOP()) {
    CPDF_Document* pDocument = nullptr;
    CPDF_Page* pPage = nullptr;
    if (m_pContext->GetPageCache()) {
      pPage = m_pContext->GetPageCache()->GetPage();
      pDocument = pPage->m_pDocument;
    } else {
      pDocument = pPageObj->AsImage()->GetImage()->GetDocument();
    }
    CPDF_Dictionary* pPageResources = pPage ? pPage->m_pPageResources : nullptr;
    CPDF_Object* pCSObj = pPageObj->AsImage()
                              ->GetImage()
                              ->GetStream()
                              ->GetDict()
                              ->GetDirectObjectBy("ColorSpace");
    CPDF_ColorSpace* pColorSpace =
        pDocument->LoadColorSpace(pCSObj, pPageResources);
    if (pColorSpace) {
      int format = pColorSpace->GetFamily();
      if (format == PDFCS_DEVICECMYK || format == PDFCS_SEPARATION ||
          format == PDFCS_DEVICEN) {
        blend_type = FXDIB_BLEND_DARKEN;
      }
      pDocument->GetPageData()->ReleaseColorSpace(pCSObj);
    }
  }
  if (!pSMaskDict && group_alpha == 1.0f && blend_type == FXDIB_BLEND_NORMAL &&
      !bTextClip && !bGroupTransparent) {
    return FALSE;
  }
  bool isolated = !!(Transparency & PDFTRANS_ISOLATED);
  if (m_bPrint) {
    FX_BOOL bRet = FALSE;
    int rendCaps = m_pDevice->GetRenderCaps();
    if (!((Transparency & PDFTRANS_ISOLATED) || pSMaskDict || bTextClip) &&
        (rendCaps & FXRC_BLEND_MODE)) {
      int oldBlend = m_curBlend;
      m_curBlend = blend_type;
      bRet = DrawObjWithBlend(pPageObj, pObj2Device);
      m_curBlend = oldBlend;
    }
    if (!bRet) {
      DrawObjWithBackground(pPageObj, pObj2Device);
    }
    return TRUE;
  }
  FX_RECT rect = pPageObj->GetBBox(pObj2Device);
  rect.Intersect(m_pDevice->GetClipBox());
  if (rect.IsEmpty()) {
    return TRUE;
  }
  CFX_Matrix deviceCTM = m_pDevice->GetCTM();
  FX_FLOAT scaleX = FXSYS_fabs(deviceCTM.a);
  FX_FLOAT scaleY = FXSYS_fabs(deviceCTM.d);
  int width = FXSYS_round((FX_FLOAT)rect.Width() * scaleX);
  int height = FXSYS_round((FX_FLOAT)rect.Height() * scaleY);
  CFX_FxgeDevice bitmap_device;
  std::unique_ptr<CFX_DIBitmap> oriDevice;
  if (!isolated && (m_pDevice->GetRenderCaps() & FXRC_GET_BITS)) {
    oriDevice.reset(new CFX_DIBitmap);
    if (!m_pDevice->CreateCompatibleBitmap(oriDevice.get(), width, height))
      return TRUE;
    m_pDevice->GetDIBits(oriDevice.get(), rect.left, rect.top);
  }
  if (!bitmap_device.Create(width, height, FXDIB_Argb, oriDevice.get()))
    return TRUE;
  CFX_DIBitmap* bitmap = bitmap_device.GetBitmap();
  bitmap->Clear(0);
  CFX_Matrix new_matrix = *pObj2Device;
  new_matrix.TranslateI(-rect.left, -rect.top);
  new_matrix.Scale(scaleX, scaleY);
  std::unique_ptr<CFX_DIBitmap> pTextMask;
  if (bTextClip) {
    pTextMask.reset(new CFX_DIBitmap);
    if (!pTextMask->Create(width, height, FXDIB_8bppMask))
      return TRUE;

    pTextMask->Clear(0);
    CFX_FxgeDevice text_device;
    text_device.Attach(pTextMask.get(), false, nullptr, false);
    for (uint32_t i = 0; i < pPageObj->m_ClipPath.GetTextCount(); i++) {
      CPDF_TextObject* textobj = pPageObj->m_ClipPath.GetText(i);
      if (!textobj) {
        break;
      }
      CFX_Matrix text_matrix;
      textobj->GetTextMatrix(&text_matrix);
      CPDF_TextRenderer::DrawTextPath(
          &text_device, textobj->m_nChars, textobj->m_pCharCodes,
          textobj->m_pCharPos, textobj->m_TextState.GetFont(),
          textobj->m_TextState.GetFontSize(), &text_matrix, &new_matrix,
          textobj->m_GraphState.GetObject(), (FX_ARGB)-1, 0, nullptr, 0);
    }
  }
  CPDF_RenderStatus bitmap_render;
  bitmap_render.Initialize(m_pContext, &bitmap_device, nullptr, m_pStopObj,
                           nullptr, nullptr, &m_Options, 0, m_bDropObjects,
                           pFormResource, TRUE);
  bitmap_render.ProcessObjectNoClip(pPageObj, &new_matrix);
  m_bStopped = bitmap_render.m_bStopped;
  if (pSMaskDict) {
    CFX_Matrix smask_matrix = *pPageObj->m_GeneralState.GetSMaskMatrix();
    smask_matrix.Concat(*pObj2Device);
    std::unique_ptr<CFX_DIBSource> pSMaskSource(
        LoadSMask(pSMaskDict, &rect, &smask_matrix));
    if (pSMaskSource)
      bitmap->MultiplyAlpha(pSMaskSource.get());
  }
  if (pTextMask) {
    bitmap->MultiplyAlpha(pTextMask.get());
    pTextMask.reset();
  }
  int32_t blitAlpha = 255;
  if (Transparency & PDFTRANS_GROUP && group_alpha != 1.0f) {
    blitAlpha = (int32_t)(group_alpha * 255);
#ifndef _SKIA_SUPPORT_
    bitmap->MultiplyAlpha(blitAlpha);
    blitAlpha = 255;
#endif
  }
  Transparency = m_Transparency;
  if (pPageObj->IsForm()) {
    Transparency |= PDFTRANS_GROUP;
  }
  CompositeDIBitmap(bitmap, rect.left, rect.top, 0, blitAlpha, blend_type,
                    Transparency);
#if defined _SKIA_SUPPORT_
  DebugVerifyDeviceIsPreMultiplied();
#endif
  return TRUE;
}
Exemple #21
0
FX_BOOL CPDF_RenderStatus::ProcessType3Text(const CPDF_TextObject* textobj, const CFX_AffineMatrix* pObj2Device)
{
    CPDF_Type3Font* pType3Font = textobj->m_TextState.GetFont()->GetType3Font();
    for (int j = 0; j < m_Type3FontCache.GetSize(); j++)
        if ((CPDF_Type3Font*)m_Type3FontCache.GetAt(j) == pType3Font) {
            return TRUE;
        }
    CFX_Matrix dCTM = m_pDevice->GetCTM();
    FX_FLOAT sa = FXSYS_fabs(dCTM.a);
    FX_FLOAT sd = FXSYS_fabs(dCTM.d);
    CFX_AffineMatrix text_matrix;
    textobj->GetTextMatrix(&text_matrix);
    CFX_AffineMatrix char_matrix = pType3Font->GetFontMatrix();
    FX_FLOAT font_size = textobj->m_TextState.GetFontSize();
    char_matrix.Scale(font_size, font_size);
    FX_ARGB fill_argb = GetFillArgb(textobj, TRUE);
    int fill_alpha = FXARGB_A(fill_argb);
    int device_class = m_pDevice->GetDeviceClass();
    FXTEXT_GLYPHPOS* pGlyphAndPos = NULL;
    if (device_class == FXDC_DISPLAY) {
        pGlyphAndPos = FX_Alloc(FXTEXT_GLYPHPOS, textobj->m_nChars);
    } else if (fill_alpha < 255) {
        return FALSE;
    }
    CPDF_RefType3Cache refTypeCache(pType3Font);
    FX_DWORD *pChars = textobj->m_pCharCodes;
    if (textobj->m_nChars == 1) {
        pChars = (FX_DWORD*)(&textobj->m_pCharCodes);
    }
    for (int iChar = 0; iChar < textobj->m_nChars; iChar ++) {
        FX_DWORD charcode = pChars[iChar];
        if (charcode == (FX_DWORD) - 1) {
            continue;
        }
        CPDF_Type3Char* pType3Char = pType3Font->LoadChar(charcode);
        if (pType3Char == NULL) {
            continue;
        }
        CFX_AffineMatrix matrix = char_matrix;
        matrix.e += iChar ? textobj->m_pCharPos[iChar - 1] : 0;
        matrix.Concat(text_matrix);
        matrix.Concat(*pObj2Device);
        if (!pType3Char->LoadBitmap(m_pContext)) {
            if (pGlyphAndPos) {
                for (int i = 0; i < iChar; i ++) {
                    FXTEXT_GLYPHPOS& glyph = pGlyphAndPos[i];
                    if (glyph.m_pGlyph == NULL) {
                        continue;
                    }
                    m_pDevice->SetBitMask(&glyph.m_pGlyph->m_Bitmap,
                                          glyph.m_OriginX + glyph.m_pGlyph->m_Left,
                                          glyph.m_OriginY - glyph.m_pGlyph->m_Top, fill_argb);
                }
                FX_Free(pGlyphAndPos);
                pGlyphAndPos = NULL;
            }
            CPDF_GraphicStates* pStates = CloneObjStates(textobj, FALSE);
            CPDF_RenderOptions Options = m_Options;
            Options.m_Flags |= RENDER_FORCE_HALFTONE | RENDER_RECT_AA;
            Options.m_Flags &= ~RENDER_FORCE_DOWNSAMPLE;
            CPDF_Dictionary* pFormResource = NULL;
            if (pType3Char->m_pForm && pType3Char->m_pForm->m_pFormDict) {
                pFormResource = pType3Char->m_pForm->m_pFormDict->GetDict(FX_BSTRC("Resources"));
            }
            if (fill_alpha == 255) {
                CPDF_RenderStatus status;
                status.Initialize(m_Level + 1, m_pContext, m_pDevice, NULL, NULL, this, pStates, &Options,
                                  pType3Char->m_pForm->m_Transparency, m_bDropObjects, pFormResource, FALSE, pType3Char, fill_argb);
                status.m_Type3FontCache.Append(m_Type3FontCache);
                status.m_Type3FontCache.Add(pType3Font);
                m_pDevice->SaveState();
                status.RenderObjectList(pType3Char->m_pForm, &matrix);
                m_pDevice->RestoreState();
            } else {
                CFX_FloatRect rect_f = pType3Char->m_pForm->CalcBoundingBox();
                rect_f.Transform(&matrix);
                FX_RECT rect = rect_f.GetOutterRect();
                CFX_FxgeDevice bitmap_device;
                if (!bitmap_device.Create((int)(rect.Width() * sa), (int)(rect.Height() * sd), FXDIB_Argb)) {
                    return TRUE;
                }
                bitmap_device.GetBitmap()->Clear(0);
                CPDF_RenderStatus status;
                status.Initialize(m_Level + 1, m_pContext, &bitmap_device, NULL, NULL, this, pStates, &Options,
                                  pType3Char->m_pForm->m_Transparency, m_bDropObjects, pFormResource, FALSE, pType3Char, fill_argb);
                status.m_Type3FontCache.Append(m_Type3FontCache);
                status.m_Type3FontCache.Add(pType3Font);
                matrix.TranslateI(-rect.left, -rect.top);
                matrix.Scale(sa, sd);
                status.RenderObjectList(pType3Char->m_pForm, &matrix);
                m_pDevice->SetDIBits(bitmap_device.GetBitmap(), rect.left, rect.top);
            }
            delete pStates;
        } else if (pType3Char->m_pBitmap) {
            if (device_class == FXDC_DISPLAY) {
                CPDF_Type3Cache* pCache = GetCachedType3(pType3Font);
                refTypeCache.m_dwCount++;
                CFX_GlyphBitmap* pBitmap = pCache->LoadGlyph(charcode, &matrix, sa, sd);
                if (pBitmap == NULL) {
                    continue;
                }
                int origin_x = FXSYS_round(matrix.e);
                int origin_y = FXSYS_round(matrix.f);
                if (pGlyphAndPos) {
                    pGlyphAndPos[iChar].m_pGlyph = pBitmap;
                    pGlyphAndPos[iChar].m_OriginX = origin_x;
                    pGlyphAndPos[iChar].m_OriginY = origin_y;
                } else {
                    m_pDevice->SetBitMask(&pBitmap->m_Bitmap, origin_x + pBitmap->m_Left, origin_y - pBitmap->m_Top, fill_argb);
                }
            } else {
                CFX_AffineMatrix image_matrix = pType3Char->m_ImageMatrix;
                image_matrix.Concat(matrix);
                CPDF_ImageRenderer renderer;
                if (renderer.Start(this, pType3Char->m_pBitmap, fill_argb, 255, &image_matrix, 0, FALSE)) {
                    renderer.Continue(NULL);
                }
                if (!renderer.m_Result) {
                    return FALSE;
                }
            }
        }
    }
    if (pGlyphAndPos) {
        FX_RECT rect = FXGE_GetGlyphsBBox(pGlyphAndPos, textobj->m_nChars, 0, sa, sd);
        CFX_DIBitmap bitmap;
        if (!bitmap.Create((int)(rect.Width() * sa), (int)(rect.Height() * sd), FXDIB_8bppMask)) {
            FX_Free(pGlyphAndPos);
            return TRUE;
        }
        bitmap.Clear(0);
        for (int iChar = 0; iChar < textobj->m_nChars; iChar ++) {
            FXTEXT_GLYPHPOS& glyph = pGlyphAndPos[iChar];
            if (glyph.m_pGlyph == NULL) {
                continue;
            }
            bitmap.TransferBitmap((int)((glyph.m_OriginX + glyph.m_pGlyph->m_Left - rect.left) * sa),
                                  (int)((glyph.m_OriginY - glyph.m_pGlyph->m_Top - rect.top) * sd),
                                  glyph.m_pGlyph->m_Bitmap.GetWidth(), glyph.m_pGlyph->m_Bitmap.GetHeight(),
                                  &glyph.m_pGlyph->m_Bitmap, 0, 0);
        }
        m_pDevice->SetBitMask(&bitmap, rect.left, rect.top, fill_argb);
        FX_Free(pGlyphAndPos);
    }
    return TRUE;
}
Exemple #22
0
FX_BOOL CPDF_RenderStatus::ProcessTransparency(
    const CPDF_PageObject* pPageObj,
    const CFX_AffineMatrix* pObj2Device) {
  const CPDF_GeneralStateData* pGeneralState = pPageObj->m_GeneralState;
  int blend_type =
      pGeneralState ? pGeneralState->m_BlendType : FXDIB_BLEND_NORMAL;
  if (blend_type == FXDIB_BLEND_UNSUPPORTED) {
    return TRUE;
  }
  CPDF_Dictionary* pSMaskDict =
      pGeneralState ? ToDictionary(pGeneralState->m_pSoftMask) : NULL;
  if (pSMaskDict) {
    if (pPageObj->m_Type == PDFPAGE_IMAGE &&
        ((CPDF_ImageObject*)pPageObj)
            ->m_pImage->GetDict()
            ->KeyExist(FX_BSTRC("SMask"))) {
      pSMaskDict = NULL;
    }
  }
  CPDF_Dictionary* pFormResource = NULL;
  FX_FLOAT group_alpha = 1.0f;
  int Transparency = m_Transparency;
  FX_BOOL bGroupTransparent = FALSE;
  if (pPageObj->m_Type == PDFPAGE_FORM) {
    CPDF_FormObject* pFormObj = (CPDF_FormObject*)pPageObj;
    const CPDF_GeneralStateData* pStateData =
        pFormObj->m_GeneralState.GetObject();
    if (pStateData) {
      group_alpha = pStateData->m_FillAlpha;
    }
    Transparency = pFormObj->m_pForm->m_Transparency;
    bGroupTransparent = !!(Transparency & PDFTRANS_ISOLATED);
    if (pFormObj->m_pForm->m_pFormDict) {
      pFormResource = pFormObj->m_pForm->m_pFormDict->GetDict("Resources");
    }
  }
  FX_BOOL bTextClip = FALSE;
  if (pPageObj->m_ClipPath.NotNull() && pPageObj->m_ClipPath.GetTextCount() &&
      m_pDevice->GetDeviceClass() == FXDC_DISPLAY &&
      !(m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_SOFT_CLIP)) {
    bTextClip = TRUE;
  }
  if ((m_Options.m_Flags & RENDER_OVERPRINT) &&
      pPageObj->m_Type == PDFPAGE_IMAGE && pGeneralState &&
      pGeneralState->m_FillOP && pGeneralState->m_StrokeOP) {
    CPDF_Document* pDocument = NULL;
    CPDF_Page* pPage = NULL;
    if (m_pContext->m_pPageCache) {
      pPage = m_pContext->m_pPageCache->GetPage();
      pDocument = pPage->m_pDocument;
    } else {
      pDocument = ((CPDF_ImageObject*)pPageObj)->m_pImage->GetDocument();
    }
    CPDF_Dictionary* pPageResources = pPage ? pPage->m_pPageResources : NULL;
    CPDF_Object* pCSObj = ((CPDF_ImageObject*)pPageObj)
                              ->m_pImage->GetStream()
                              ->GetDict()
                              ->GetElementValue(FX_BSTRC("ColorSpace"));
    CPDF_ColorSpace* pColorSpace =
        pDocument->LoadColorSpace(pCSObj, pPageResources);
    if (pColorSpace) {
      int format = pColorSpace->GetFamily();
      if (format == PDFCS_DEVICECMYK || format == PDFCS_SEPARATION ||
          format == PDFCS_DEVICEN) {
        blend_type = FXDIB_BLEND_DARKEN;
      }
      pDocument->GetPageData()->ReleaseColorSpace(pCSObj);
    }
  }
  if (pSMaskDict == NULL && group_alpha == 1.0f &&
      blend_type == FXDIB_BLEND_NORMAL && !bTextClip && !bGroupTransparent) {
    return FALSE;
  }
  FX_BOOL isolated = Transparency & PDFTRANS_ISOLATED;
  if (m_bPrint) {
    FX_BOOL bRet = FALSE;
    int rendCaps = m_pDevice->GetRenderCaps();
    if (!((Transparency & PDFTRANS_ISOLATED) || pSMaskDict || bTextClip) &&
        (rendCaps & FXRC_BLEND_MODE)) {
      int oldBlend = m_curBlend;
      m_curBlend = blend_type;
      bRet = DrawObjWithBlend(pPageObj, pObj2Device);
      m_curBlend = oldBlend;
    }
    if (!bRet) {
      DrawObjWithBackground(pPageObj, pObj2Device);
    }
    return TRUE;
  }
  FX_RECT rect = pPageObj->GetBBox(pObj2Device);
  rect.Intersect(m_pDevice->GetClipBox());
  if (rect.IsEmpty()) {
    return TRUE;
  }
  CFX_Matrix deviceCTM = m_pDevice->GetCTM();
  FX_FLOAT scaleX = FXSYS_fabs(deviceCTM.a);
  FX_FLOAT scaleY = FXSYS_fabs(deviceCTM.d);
  int width = FXSYS_round((FX_FLOAT)rect.Width() * scaleX);
  int height = FXSYS_round((FX_FLOAT)rect.Height() * scaleY);
  CFX_FxgeDevice bitmap_device;
  nonstd::unique_ptr<CFX_DIBitmap> oriDevice;
  if (!isolated && (m_pDevice->GetRenderCaps() & FXRC_GET_BITS)) {
    oriDevice.reset(new CFX_DIBitmap);
    if (!m_pDevice->CreateCompatibleBitmap(oriDevice.get(), width, height))
      return TRUE;

    m_pDevice->GetDIBits(oriDevice.get(), rect.left, rect.top);
  }
  if (!bitmap_device.Create(width, height, FXDIB_Argb, 0, oriDevice.get()))
    return TRUE;

  CFX_DIBitmap* bitmap = bitmap_device.GetBitmap();
  bitmap->Clear(0);
  CFX_AffineMatrix new_matrix = *pObj2Device;
  new_matrix.TranslateI(-rect.left, -rect.top);
  new_matrix.Scale(scaleX, scaleY);
  nonstd::unique_ptr<CFX_DIBitmap> pTextMask;
  if (bTextClip) {
    pTextMask.reset(new CFX_DIBitmap);
    if (!pTextMask->Create(width, height, FXDIB_8bppMask))
      return TRUE;

    pTextMask->Clear(0);
    CFX_FxgeDevice text_device;
    text_device.Attach(pTextMask.get());
    for (FX_DWORD i = 0; i < pPageObj->m_ClipPath.GetTextCount(); i++) {
      CPDF_TextObject* textobj = pPageObj->m_ClipPath.GetText(i);
      if (textobj == NULL) {
        break;
      }
      CFX_AffineMatrix text_matrix;
      textobj->GetTextMatrix(&text_matrix);
      CPDF_TextRenderer::DrawTextPath(
          &text_device, textobj->m_nChars, textobj->m_pCharCodes,
          textobj->m_pCharPos, textobj->m_TextState.GetFont(),
          textobj->m_TextState.GetFontSize(), &text_matrix, &new_matrix,
          textobj->m_GraphState, (FX_ARGB)-1, 0, NULL);
    }
  }
  CPDF_RenderStatus bitmap_render;
  bitmap_render.Initialize(m_pContext, &bitmap_device, NULL, m_pStopObj, NULL,
                           NULL, &m_Options, 0, m_bDropObjects, pFormResource,
                           TRUE);
  bitmap_render.ProcessObjectNoClip(pPageObj, &new_matrix);
  m_bStopped = bitmap_render.m_bStopped;
  if (pSMaskDict) {
    CFX_AffineMatrix smask_matrix;
    FXSYS_memcpy(&smask_matrix, pGeneralState->m_SMaskMatrix,
                 sizeof smask_matrix);
    smask_matrix.Concat(*pObj2Device);
    nonstd::unique_ptr<CFX_DIBSource> pSMaskSource(
        LoadSMask(pSMaskDict, &rect, &smask_matrix));
    if (pSMaskSource)
      bitmap->MultiplyAlpha(pSMaskSource.get());
  }
  if (pTextMask) {
    bitmap->MultiplyAlpha(pTextMask.get());
    pTextMask.reset();
  }
  if (Transparency & PDFTRANS_GROUP && group_alpha != 1.0f) {
    bitmap->MultiplyAlpha((int32_t)(group_alpha * 255));
  }
  Transparency = m_Transparency;
  if (pPageObj->m_Type == PDFPAGE_FORM) {
    Transparency |= PDFTRANS_GROUP;
  }
  CompositeDIBitmap(bitmap, rect.left, rect.top, 0, 255, blend_type,
                    Transparency);
  return TRUE;
}
FX_BOOL	CPDF_ImageRenderer::DrawPatternImage(const CFX_Matrix* pObj2Device)
{
    if (m_pRenderStatus->m_bPrint && !(m_pRenderStatus->m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) {
        m_Result = FALSE;
        return FALSE;
    }
    FX_RECT rect = m_ImageMatrix.GetUnitRect().GetOutterRect();
    rect.Intersect(m_pRenderStatus->m_pDevice->GetClipBox());
    if (rect.IsEmpty()) {
        return FALSE;
    }
    CFX_AffineMatrix new_matrix = m_ImageMatrix;
    new_matrix.TranslateI(-rect.left, -rect.top);
    int width = rect.Width();
    int height = rect.Height();
    CFX_FxgeDevice bitmap_device1;
    if (!bitmap_device1.Create(rect.Width(), rect.Height(), FXDIB_Rgb32)) {
        return TRUE;
    }
    bitmap_device1.GetBitmap()->Clear(0xffffff);
    {
        CPDF_RenderStatus bitmap_render;
        bitmap_render.Initialize(m_pRenderStatus->m_Level + 1, m_pRenderStatus->m_pContext, &bitmap_device1, NULL, NULL,
                                 NULL, NULL, &m_pRenderStatus->m_Options, 0, m_pRenderStatus->m_bDropObjects, NULL, TRUE);
        CFX_Matrix patternDevice = *pObj2Device;
        patternDevice.Translate((FX_FLOAT) - rect.left, (FX_FLOAT) - rect.top);
        if(m_pPattern->m_PatternType == PATTERN_TILING) {
            bitmap_render.DrawTilingPattern((CPDF_TilingPattern*)m_pPattern, m_pImageObject, &patternDevice, FALSE);
        } else {
            bitmap_render.DrawShadingPattern((CPDF_ShadingPattern*)m_pPattern, m_pImageObject, &patternDevice, FALSE);
        }
    }
    {
        CFX_FxgeDevice bitmap_device2;
        if (!bitmap_device2.Create(rect.Width(), rect.Height(), FXDIB_8bppRgb)) {
            return TRUE;
        }
        bitmap_device2.GetBitmap()->Clear(0);
        CPDF_RenderStatus bitmap_render;
        bitmap_render.Initialize(m_pRenderStatus->m_Level + 1, m_pRenderStatus->m_pContext, &bitmap_device2, NULL, NULL,
                                 NULL, NULL, NULL, 0, m_pRenderStatus->m_bDropObjects, NULL, TRUE);
        CPDF_ImageRenderer image_render;
        if (image_render.Start(&bitmap_render, m_pDIBSource, 0xffffffff, 255, &new_matrix, m_Flags, TRUE)) {
            image_render.Continue(NULL);
        }
        if (m_Loader.m_MatteColor != 0xffffffff) {
            int matte_r = FXARGB_R(m_Loader.m_MatteColor);
            int matte_g = FXARGB_G(m_Loader.m_MatteColor);
            int matte_b = FXARGB_B(m_Loader.m_MatteColor);
            for (int row = 0; row < height; row ++) {
                FX_LPBYTE dest_scan = (FX_LPBYTE)bitmap_device1.GetBitmap()->GetScanline(row);
                FX_LPCBYTE mask_scan = bitmap_device2.GetBitmap()->GetScanline(row);
                for (int col = 0; col < width; col ++) {
                    int alpha = *mask_scan ++;
                    if (alpha) {
                        int orig = (*dest_scan - matte_b) * 255 / alpha + matte_b;
                        if (orig < 0) {
                            orig = 0;
                        } else if (orig > 255) {
                            orig = 255;
                        }
                        *dest_scan++ = orig;
                        orig = (*dest_scan - matte_g) * 255 / alpha + matte_g;
                        if (orig < 0) {
                            orig = 0;
                        } else if (orig > 255) {
                            orig = 255;
                        }
                        *dest_scan++ = orig;
                        orig = (*dest_scan - matte_r) * 255 / alpha + matte_r;
                        if (orig < 0) {
                            orig = 0;
                        } else if (orig > 255) {
                            orig = 255;
                        }
                        *dest_scan++ = orig;
                        dest_scan ++;
                    } else {
                        dest_scan += 4;
                    }
                }
            }
        }
        bitmap_device2.GetBitmap()->ConvertFormat(FXDIB_8bppMask);
        bitmap_device1.GetBitmap()->MultiplyAlpha(bitmap_device2.GetBitmap());
        bitmap_device1.GetBitmap()->MultiplyAlpha(255);
    }
    m_pRenderStatus->m_pDevice->SetDIBits(bitmap_device1.GetBitmap(), rect.left, rect.top, m_BlendType);
    return FALSE;
}
bool CPDF_ImageRenderer::DrawPatternImage(const CFX_Matrix* pObj2Device) {
  if (m_pRenderStatus->m_bPrint &&
      !(m_pRenderStatus->m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) {
    m_Result = false;
    return false;
  }
  FX_RECT rect = m_ImageMatrix.GetUnitRect().GetOuterRect();
  rect.Intersect(m_pRenderStatus->m_pDevice->GetClipBox());
  if (rect.IsEmpty()) {
    return false;
  }
  CFX_Matrix new_matrix = m_ImageMatrix;
  new_matrix.TranslateI(-rect.left, -rect.top);
  int width = rect.Width();
  int height = rect.Height();
  CFX_FxgeDevice bitmap_device1;
  if (!bitmap_device1.Create(rect.Width(), rect.Height(), FXDIB_Rgb32, nullptr))
    return true;

  bitmap_device1.GetBitmap()->Clear(0xffffff);
  {
    CPDF_RenderStatus bitmap_render;
    bitmap_render.Initialize(m_pRenderStatus->m_pContext, &bitmap_device1,
                             nullptr, nullptr, nullptr, nullptr,
                             &m_pRenderStatus->m_Options, 0,
                             m_pRenderStatus->m_bDropObjects, nullptr, true);
    CFX_Matrix patternDevice = *pObj2Device;
    patternDevice.Translate((FX_FLOAT)-rect.left, (FX_FLOAT)-rect.top);
    if (CPDF_TilingPattern* pTilingPattern = m_pPattern->AsTilingPattern()) {
      bitmap_render.DrawTilingPattern(pTilingPattern, m_pImageObject,
                                      &patternDevice, false);
    } else if (CPDF_ShadingPattern* pShadingPattern =
                   m_pPattern->AsShadingPattern()) {
      bitmap_render.DrawShadingPattern(pShadingPattern, m_pImageObject,
                                       &patternDevice, false);
    }
  }
  {
    CFX_FxgeDevice bitmap_device2;
    if (!bitmap_device2.Create(rect.Width(), rect.Height(), FXDIB_8bppRgb,
                               nullptr)) {
      return true;
    }
    bitmap_device2.GetBitmap()->Clear(0);
    CPDF_RenderStatus bitmap_render;
    bitmap_render.Initialize(m_pRenderStatus->m_pContext, &bitmap_device2,
                             nullptr, nullptr, nullptr, nullptr, nullptr, 0,
                             m_pRenderStatus->m_bDropObjects, nullptr, true);
    CPDF_ImageRenderer image_render;
    if (image_render.Start(&bitmap_render, m_pDIBSource, 0xffffffff, 255,
                           &new_matrix, m_Flags, true)) {
      image_render.Continue(nullptr);
    }
    if (m_Loader.m_MatteColor != 0xffffffff) {
      int matte_r = FXARGB_R(m_Loader.m_MatteColor);
      int matte_g = FXARGB_G(m_Loader.m_MatteColor);
      int matte_b = FXARGB_B(m_Loader.m_MatteColor);
      for (int row = 0; row < height; row++) {
        uint8_t* dest_scan =
            (uint8_t*)bitmap_device1.GetBitmap()->GetScanline(row);
        const uint8_t* mask_scan = bitmap_device2.GetBitmap()->GetScanline(row);
        for (int col = 0; col < width; col++) {
          int alpha = *mask_scan++;
          if (alpha) {
            int orig = (*dest_scan - matte_b) * 255 / alpha + matte_b;
            if (orig < 0) {
              orig = 0;
            } else if (orig > 255) {
              orig = 255;
            }
            *dest_scan++ = orig;
            orig = (*dest_scan - matte_g) * 255 / alpha + matte_g;
            if (orig < 0) {
              orig = 0;
            } else if (orig > 255) {
              orig = 255;
            }
            *dest_scan++ = orig;
            orig = (*dest_scan - matte_r) * 255 / alpha + matte_r;
            if (orig < 0) {
              orig = 0;
            } else if (orig > 255) {
              orig = 255;
            }
            *dest_scan++ = orig;
            dest_scan++;
          } else {
            dest_scan += 4;
          }
        }
      }
    }
    bitmap_device2.GetBitmap()->ConvertFormat(FXDIB_8bppMask);
    bitmap_device1.GetBitmap()->MultiplyAlpha(bitmap_device2.GetBitmap());
    bitmap_device1.GetBitmap()->MultiplyAlpha(255);
  }
  m_pRenderStatus->m_pDevice->SetDIBitsWithBlend(
      bitmap_device1.GetBitmap(), rect.left, rect.top, m_BlendType);
  return false;
}
FX_RECT CPDF_ImageRenderer::GetDrawRect() const {
  FX_RECT rect = m_ImageMatrix.GetUnitRect().GetOuterRect();
  rect.Intersect(m_pRenderStatus->m_pDevice->GetClipBox());
  return rect;
}
Exemple #26
0
FX_BOOL CPDF_ImageRenderer::DrawMaskedImage() {
    if (m_pRenderStatus->m_bPrint &&
            !(m_pRenderStatus->m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) {
        m_Result = FALSE;
        return FALSE;
    }
    FX_RECT rect = m_ImageMatrix.GetUnitRect().GetOutterRect();
    rect.Intersect(m_pRenderStatus->m_pDevice->GetClipBox());
    if (rect.IsEmpty()) {
        return FALSE;
    }
    CFX_AffineMatrix new_matrix = m_ImageMatrix;
    new_matrix.TranslateI(-rect.left, -rect.top);
    int width = rect.Width();
    int height = rect.Height();
    CFX_FxgeDevice bitmap_device1;
    if (!bitmap_device1.Create(width, height, FXDIB_Rgb32)) {
        return TRUE;
    }
    bitmap_device1.GetBitmap()->Clear(0xffffff);
    {
        CPDF_RenderStatus bitmap_render;
        bitmap_render.Initialize(m_pRenderStatus->m_pContext, &bitmap_device1, NULL,
                                 NULL, NULL, NULL, NULL, 0,
                                 m_pRenderStatus->m_bDropObjects, NULL, TRUE);
        CPDF_ImageRenderer image_render;
        if (image_render.Start(&bitmap_render, m_pDIBSource, 0, 255, &new_matrix,
                               m_Flags, TRUE)) {
            image_render.Continue(NULL);
        }
    }
    {
        CFX_FxgeDevice bitmap_device2;
        if (!bitmap_device2.Create(width, height, FXDIB_8bppRgb)) {
            return TRUE;
        }
        bitmap_device2.GetBitmap()->Clear(0);
        CPDF_RenderStatus bitmap_render;
        bitmap_render.Initialize(m_pRenderStatus->m_pContext, &bitmap_device2, NULL,
                                 NULL, NULL, NULL, NULL, 0,
                                 m_pRenderStatus->m_bDropObjects, NULL, TRUE);
        CPDF_ImageRenderer image_render;
        if (image_render.Start(&bitmap_render, m_Loader.m_pMask, 0xffffffff, 255,
                               &new_matrix, m_Flags, TRUE)) {
            image_render.Continue(NULL);
        }
        if (m_Loader.m_MatteColor != 0xffffffff) {
            int matte_r = FXARGB_R(m_Loader.m_MatteColor);
            int matte_g = FXARGB_G(m_Loader.m_MatteColor);
            int matte_b = FXARGB_B(m_Loader.m_MatteColor);
            for (int row = 0; row < height; row++) {
                uint8_t* dest_scan =
                    (uint8_t*)bitmap_device1.GetBitmap()->GetScanline(row);
                const uint8_t* mask_scan = bitmap_device2.GetBitmap()->GetScanline(row);
                for (int col = 0; col < width; col++) {
                    int alpha = *mask_scan++;
                    if (alpha) {
                        int orig = (*dest_scan - matte_b) * 255 / alpha + matte_b;
                        if (orig < 0) {
                            orig = 0;
                        } else if (orig > 255) {
                            orig = 255;
                        }
                        *dest_scan++ = orig;
                        orig = (*dest_scan - matte_g) * 255 / alpha + matte_g;
                        if (orig < 0) {
                            orig = 0;
                        } else if (orig > 255) {
                            orig = 255;
                        }
                        *dest_scan++ = orig;
                        orig = (*dest_scan - matte_r) * 255 / alpha + matte_r;
                        if (orig < 0) {
                            orig = 0;
                        } else if (orig > 255) {
                            orig = 255;
                        }
                        *dest_scan++ = orig;
                        dest_scan++;
                    } else {
                        dest_scan += 4;
                    }
                }
            }
        }
        bitmap_device2.GetBitmap()->ConvertFormat(FXDIB_8bppMask);
        bitmap_device1.GetBitmap()->MultiplyAlpha(bitmap_device2.GetBitmap());
        if (m_BitmapAlpha < 255) {
            bitmap_device1.GetBitmap()->MultiplyAlpha(m_BitmapAlpha);
        }
    }
    m_pRenderStatus->m_pDevice->SetDIBits(bitmap_device1.GetBitmap(), rect.left,
                                          rect.top, m_BlendType);
    return FALSE;
}