示例#1
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;
}
示例#2
0
void CPDF_DeviceBuffer::OutputToDevice() {
  if (m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_GET_BITS) {
    if (m_Matrix.a == 1.0f && m_Matrix.d == 1.0f) {
      m_pDevice->SetDIBits(m_pBitmap.get(), m_Rect.left, m_Rect.top);
    } else {
      m_pDevice->StretchDIBits(m_pBitmap.get(), m_Rect.left, m_Rect.top,
                               m_Rect.Width(), m_Rect.Height());
    }
  } else {
    CFX_DIBitmap buffer;
    m_pDevice->CreateCompatibleBitmap(&buffer, m_pBitmap->GetWidth(),
                                      m_pBitmap->GetHeight());
    m_pContext->GetBackground(&buffer, m_pObject, nullptr, &m_Matrix);
    buffer.CompositeBitmap(0, 0, buffer.GetWidth(), buffer.GetHeight(),
                           m_pBitmap.get(), 0, 0);
    m_pDevice->StretchDIBits(&buffer, m_Rect.left, m_Rect.top, m_Rect.Width(),
                             m_Rect.Height());
  }
}
void CPDF_RenderStatus::DrawTilingPattern(CPDF_TilingPattern* pPattern,
                                          CPDF_PageObject* pPageObj,
                                          const CFX_Matrix* pObj2Device,
                                          FX_BOOL bStroke) {
  if (!pPattern->Load()) {
    return;
  }
  m_pDevice->SaveState();
  if (pPageObj->m_Type == PDFPAGE_PATH) {
    if (!SelectClipPath((CPDF_PathObject*)pPageObj, pObj2Device, bStroke)) {
      m_pDevice->RestoreState();
      return;
    }
  } else if (pPageObj->m_Type == PDFPAGE_IMAGE) {
    FX_RECT rect = pPageObj->GetBBox(pObj2Device);
    m_pDevice->SetClip_Rect(&rect);
  } else {
    return;
  }
  FX_RECT clip_box = m_pDevice->GetClipBox();
  if (clip_box.IsEmpty()) {
    m_pDevice->RestoreState();
    return;
  }
  CFX_Matrix dCTM = m_pDevice->GetCTM();
  FX_FLOAT sa = FXSYS_fabs(dCTM.a);
  FX_FLOAT sd = FXSYS_fabs(dCTM.d);
  clip_box.right = clip_box.left + (int32_t)FXSYS_ceil(clip_box.Width() * sa);
  clip_box.bottom = clip_box.top + (int32_t)FXSYS_ceil(clip_box.Height() * sd);
  CFX_Matrix mtPattern2Device = pPattern->m_Pattern2Form;
  mtPattern2Device.Concat(*pObj2Device);
  GetScaledMatrix(mtPattern2Device);
  FX_BOOL bAligned = FALSE;
  if (pPattern->m_BBox.left == 0 && pPattern->m_BBox.bottom == 0 &&
      pPattern->m_BBox.right == pPattern->m_XStep &&
      pPattern->m_BBox.top == pPattern->m_YStep &&
      (mtPattern2Device.IsScaled() || mtPattern2Device.Is90Rotated())) {
    bAligned = TRUE;
  }
  CFX_FloatRect cell_bbox = pPattern->m_BBox;
  mtPattern2Device.TransformRect(cell_bbox);
  int width = (int)FXSYS_ceil(cell_bbox.Width());
  int height = (int)FXSYS_ceil(cell_bbox.Height());
  if (width == 0) {
    width = 1;
  }
  if (height == 0) {
    height = 1;
  }
  int min_col, max_col, min_row, max_row;
  CFX_Matrix mtDevice2Pattern;
  mtDevice2Pattern.SetReverse(mtPattern2Device);
  CFX_FloatRect clip_box_p(clip_box);
  clip_box_p.Transform(&mtDevice2Pattern);
  min_col = (int)FXSYS_ceil(
      FXSYS_Div(clip_box_p.left - pPattern->m_BBox.right, pPattern->m_XStep));
  max_col = (int)FXSYS_floor(
      FXSYS_Div(clip_box_p.right - pPattern->m_BBox.left, pPattern->m_XStep));
  min_row = (int)FXSYS_ceil(
      FXSYS_Div(clip_box_p.bottom - pPattern->m_BBox.top, pPattern->m_YStep));
  max_row = (int)FXSYS_floor(
      FXSYS_Div(clip_box_p.top - pPattern->m_BBox.bottom, pPattern->m_YStep));
  if (width > clip_box.Width() || height > clip_box.Height() ||
      width * height > clip_box.Width() * clip_box.Height()) {
    CPDF_GraphicStates* pStates = NULL;
    if (!pPattern->m_bColored) {
      pStates = CloneObjStates(pPageObj, bStroke);
    }
    CPDF_Dictionary* pFormResource = NULL;
    if (pPattern->m_pForm->m_pFormDict) {
      pFormResource = pPattern->m_pForm->m_pFormDict->GetDict("Resources");
    }
    for (int col = min_col; col <= max_col; col++)
      for (int row = min_row; row <= max_row; row++) {
        FX_FLOAT orig_x, orig_y;
        orig_x = col * pPattern->m_XStep;
        orig_y = row * pPattern->m_YStep;
        mtPattern2Device.Transform(orig_x, orig_y);
        CFX_Matrix matrix = *pObj2Device;
        matrix.Translate(orig_x - mtPattern2Device.e,
                         orig_y - mtPattern2Device.f);
        m_pDevice->SaveState();
        CPDF_RenderStatus status;
        status.Initialize(m_pContext, m_pDevice, NULL, NULL, this, pStates,
                          &m_Options, pPattern->m_pForm->m_Transparency,
                          m_bDropObjects, pFormResource);
        status.RenderObjectList(pPattern->m_pForm, &matrix);
        m_pDevice->RestoreState();
      }
    m_pDevice->RestoreState();
    delete pStates;
    return;
  }
  if (bAligned) {
    int orig_x = FXSYS_round(mtPattern2Device.e);
    int orig_y = FXSYS_round(mtPattern2Device.f);
    min_col = (clip_box.left - orig_x) / width;
    if (clip_box.left < orig_x) {
      min_col--;
    }
    max_col = (clip_box.right - orig_x) / width;
    if (clip_box.right <= orig_x) {
      max_col--;
    }
    min_row = (clip_box.top - orig_y) / height;
    if (clip_box.top < orig_y) {
      min_row--;
    }
    max_row = (clip_box.bottom - orig_y) / height;
    if (clip_box.bottom <= orig_y) {
      max_row--;
    }
  }
  FX_FLOAT left_offset = cell_bbox.left - mtPattern2Device.e;
  FX_FLOAT top_offset = cell_bbox.bottom - mtPattern2Device.f;
  CFX_DIBitmap* pPatternBitmap = NULL;
  if (width * height < 16) {
    CFX_DIBitmap* pEnlargedBitmap =
        DrawPatternBitmap(m_pContext->m_pDocument, m_pContext->m_pPageCache,
                          pPattern, pObj2Device, 8, 8, m_Options.m_Flags);
    pPatternBitmap = pEnlargedBitmap->StretchTo(width, height);
    delete pEnlargedBitmap;
  } else {
    pPatternBitmap = DrawPatternBitmap(
        m_pContext->m_pDocument, m_pContext->m_pPageCache, pPattern,
        pObj2Device, width, height, m_Options.m_Flags);
  }
  if (!pPatternBitmap) {
    m_pDevice->RestoreState();
    return;
  }
  if (m_Options.m_ColorMode == RENDER_COLOR_GRAY) {
    pPatternBitmap->ConvertColorScale(m_Options.m_ForeColor,
                                      m_Options.m_BackColor);
  }
  FX_ARGB fill_argb = GetFillArgb(pPageObj);
  int clip_width = clip_box.right - clip_box.left;
  int clip_height = clip_box.bottom - clip_box.top;
  CFX_DIBitmap screen;
  if (!screen.Create(clip_width, clip_height, FXDIB_Argb)) {
    return;
  }
  screen.Clear(0);
  FX_DWORD* src_buf = (FX_DWORD*)pPatternBitmap->GetBuffer();
  for (int col = min_col; col <= max_col; col++) {
    for (int row = min_row; row <= max_row; row++) {
      int start_x, start_y;
      if (bAligned) {
        start_x = FXSYS_round(mtPattern2Device.e) + col * width - clip_box.left;
        start_y = FXSYS_round(mtPattern2Device.f) + row * height - clip_box.top;
      } else {
        FX_FLOAT orig_x = col * pPattern->m_XStep;
        FX_FLOAT orig_y = row * pPattern->m_YStep;
        mtPattern2Device.Transform(orig_x, orig_y);
        start_x = FXSYS_round(orig_x + left_offset) - clip_box.left;
        start_y = FXSYS_round(orig_y + top_offset) - clip_box.top;
      }
      if (width == 1 && height == 1) {
        if (start_x < 0 || start_x >= clip_box.Width() || start_y < 0 ||
            start_y >= clip_box.Height()) {
          continue;
        }
        FX_DWORD* dest_buf =
            (FX_DWORD*)(screen.GetBuffer() + screen.GetPitch() * start_y +
                        start_x * 4);
        if (pPattern->m_bColored) {
          *dest_buf = *src_buf;
        } else {
          *dest_buf = (*(uint8_t*)src_buf << 24) | (fill_argb & 0xffffff);
        }
      } else {
        if (pPattern->m_bColored) {
          screen.CompositeBitmap(start_x, start_y, width, height,
                                 pPatternBitmap, 0, 0);
        } else {
          screen.CompositeMask(start_x, start_y, width, height, pPatternBitmap,
                               fill_argb, 0, 0);
        }
      }
    }
  }
  CompositeDIBitmap(&screen, clip_box.left, clip_box.top, 0, 255,
                    FXDIB_BLEND_NORMAL, FALSE);
  m_pDevice->RestoreState();
  delete pPatternBitmap;
}
示例#4
0
void CPDF_RenderStatus::CompositeDIBitmap(CFX_DIBitmap* pDIBitmap,
        int left,
        int top,
        FX_ARGB mask_argb,
        int bitmap_alpha,
        int blend_mode,
        int Transparency) {
    if (pDIBitmap == NULL) {
        return;
    }
    FX_BOOL bIsolated = Transparency & PDFTRANS_ISOLATED;
    FX_BOOL bGroup = Transparency & PDFTRANS_GROUP;
    if (blend_mode == FXDIB_BLEND_NORMAL) {
        if (!pDIBitmap->IsAlphaMask()) {
            if (bitmap_alpha < 255) {
                pDIBitmap->MultiplyAlpha(bitmap_alpha);
            }
            if (m_pDevice->SetDIBits(pDIBitmap, left, top)) {
                return;
            }
        } else {
            FX_DWORD fill_argb = m_Options.TranslateColor(mask_argb);
            if (bitmap_alpha < 255) {
                ((uint8_t*)&fill_argb)[3] =
                    ((uint8_t*)&fill_argb)[3] * bitmap_alpha / 255;
            }
            if (m_pDevice->SetBitMask(pDIBitmap, left, top, fill_argb)) {
                return;
            }
        }
    }
    FX_BOOL bBackAlphaRequired = blend_mode && bIsolated && !m_bDropObjects;
    FX_BOOL bGetBackGround =
        ((m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT)) ||
        (!(m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT) &&
         (m_pDevice->GetRenderCaps() & FXRC_GET_BITS) && !bBackAlphaRequired);
    if (bGetBackGround) {
        if (bIsolated || !bGroup) {
            if (pDIBitmap->IsAlphaMask()) {
                return;
            }
            m_pDevice->SetDIBits(pDIBitmap, left, top, blend_mode);
        } else {
            FX_RECT rect(left, top, left + pDIBitmap->GetWidth(),
                         top + pDIBitmap->GetHeight());
            rect.Intersect(m_pDevice->GetClipBox());
            CFX_DIBitmap* pClone = NULL;
            FX_BOOL bClone = FALSE;
            if (m_pDevice->GetBackDrop() && m_pDevice->GetBitmap()) {
                bClone = TRUE;
                pClone = m_pDevice->GetBackDrop()->Clone(&rect);
                CFX_DIBitmap* pForeBitmap = m_pDevice->GetBitmap();
                pClone->CompositeBitmap(0, 0, pClone->GetWidth(), pClone->GetHeight(),
                                        pForeBitmap, rect.left, rect.top);
                left = left >= 0 ? 0 : left;
                top = top >= 0 ? 0 : top;
                if (!pDIBitmap->IsAlphaMask())
                    pClone->CompositeBitmap(0, 0, pClone->GetWidth(), pClone->GetHeight(),
                                            pDIBitmap, left, top, blend_mode);
                else
                    pClone->CompositeMask(0, 0, pClone->GetWidth(), pClone->GetHeight(),
                                          pDIBitmap, mask_argb, left, top, blend_mode);
            } else {
                pClone = pDIBitmap;
            }
            if (m_pDevice->GetBackDrop()) {
                m_pDevice->SetDIBits(pClone, rect.left, rect.top);
            } else {
                if (pDIBitmap->IsAlphaMask()) {
                    return;
                }
                m_pDevice->SetDIBits(pDIBitmap, rect.left, rect.top, blend_mode);
            }
            if (bClone) {
                delete pClone;
            }
        }
        return;
    }
    int back_left, back_top;
    FX_RECT rect(left, top, left + pDIBitmap->GetWidth(),
                 top + pDIBitmap->GetHeight());
    nonstd::unique_ptr<CFX_DIBitmap> pBackdrop(
        GetBackdrop(m_pCurObj, rect, back_left, back_top,
                    blend_mode > FXDIB_BLEND_NORMAL && bIsolated));
    if (!pBackdrop)
        return;

    if (!pDIBitmap->IsAlphaMask()) {
        pBackdrop->CompositeBitmap(left - back_left, top - back_top,
                                   pDIBitmap->GetWidth(), pDIBitmap->GetHeight(),
                                   pDIBitmap, 0, 0, blend_mode);
    } else {
        pBackdrop->CompositeMask(left - back_left, top - back_top,
                                 pDIBitmap->GetWidth(), pDIBitmap->GetHeight(),
                                 pDIBitmap, mask_argb, 0, 0, blend_mode);
    }

    nonstd::unique_ptr<CFX_DIBitmap> pBackdrop1(new CFX_DIBitmap);
    pBackdrop1->Create(pBackdrop->GetWidth(), pBackdrop->GetHeight(),
                       FXDIB_Rgb32);
    pBackdrop1->Clear((FX_DWORD)-1);
    pBackdrop1->CompositeBitmap(0, 0, pBackdrop->GetWidth(),
                                pBackdrop->GetHeight(), pBackdrop.get(), 0, 0);
    pBackdrop = nonstd::move(pBackdrop1);
    m_pDevice->SetDIBits(pBackdrop.get(), back_left, back_top);
}
示例#5
0
DLLEXPORT void STDCALL FPDF_RenderPage(HDC dc, FPDF_PAGE page, int start_x, int start_y, int size_x, int size_y,
						int rotate, int flags)
{
	if (page==NULL) return;
	CPDF_Page* pPage = (CPDF_Page*)page;

	CRenderContext* pContext = new CRenderContext;
	pPage->SetPrivateData((void*)1, pContext, DropContext);

#ifndef _WIN32_WCE
	CFX_DIBitmap* pBitmap = NULL;
	FX_BOOL bBackgroundAlphaNeeded=FALSE;
	bBackgroundAlphaNeeded = pPage->BackgroundAlphaNeeded();
	if (bBackgroundAlphaNeeded)
	{

		pBitmap = new CFX_DIBitmap;
		pBitmap->Create(size_x, size_y, FXDIB_Argb);
		pBitmap->Clear(0x00ffffff);
#ifdef _SKIA_SUPPORT_
		pContext->m_pDevice = new CFX_SkiaDevice;
		((CFX_SkiaDevice*)pContext->m_pDevice)->Attach((CFX_DIBitmap*)pBitmap);
#else
		pContext->m_pDevice = new CFX_FxgeDevice;
		((CFX_FxgeDevice*)pContext->m_pDevice)->Attach((CFX_DIBitmap*)pBitmap);
#endif
	}
	else
	    pContext->m_pDevice = new CFX_WindowsDevice(dc);

	Func_RenderPage(pContext, page, start_x, start_y, size_x, size_y, rotate, flags,TRUE,NULL);

	if (bBackgroundAlphaNeeded)
	{
		if (pBitmap)
		{
			CFX_WindowsDevice WinDC(dc);

 			if (WinDC.GetDeviceCaps(FXDC_DEVICE_CLASS) == FXDC_PRINTER)
 			{
				CFX_DIBitmap* pDst = new CFX_DIBitmap;
				int pitch = pBitmap->GetPitch();
				pDst->Create(size_x, size_y, FXDIB_Rgb32);
				FXSYS_memset(pDst->GetBuffer(), -1, pitch*size_y);
				pDst->CompositeBitmap(0, 0, size_x, size_y, pBitmap, 0, 0, FXDIB_BLEND_NORMAL, NULL, FALSE, NULL);
				WinDC.StretchDIBits(pDst,0,0,size_x,size_y);
				delete pDst;
 			}
 			else
 				WinDC.SetDIBits(pBitmap,0,0);

		}
	}
#else
	// get clip region
	RECT rect, cliprect;
	rect.left = start_x;
	rect.top = start_y;
	rect.right = start_x + size_x;
	rect.bottom = start_y + size_y;
	GetClipBox(dc, &cliprect);
	IntersectRect(&rect, &rect, &cliprect);
	int width = rect.right - rect.left;
	int height = rect.bottom - rect.top;

#ifdef DEBUG_TRACE
	{
		char str[128];
		memset(str, 0, sizeof(str));
		FXSYS_snprintf(str, sizeof(str) - 1, "Rendering DIB %d x %d", width, height);
		CPDF_ModuleMgr::Get()->ReportError(999, str);
	}
#endif

	// Create a DIB section
	LPVOID pBuffer;
	BITMAPINFOHEADER bmih;
	FXSYS_memset(&bmih, 0, sizeof bmih);
	bmih.biSize = sizeof bmih;
	bmih.biBitCount = 24;
	bmih.biHeight = -height;
	bmih.biPlanes = 1;
	bmih.biWidth = width;
	pContext->m_hBitmap = CreateDIBSection(dc, (BITMAPINFO*)&bmih, DIB_RGB_COLORS, &pBuffer, NULL, 0);
	if (pContext->m_hBitmap == NULL) {
#if defined(DEBUG) || defined(_DEBUG)
		char str[128];
		memset(str, 0, sizeof(str));
		FXSYS_snprintf(str, sizeof(str) - 1, "Error CreateDIBSection: %d x %d, error code = %d", width, height, GetLastError());
		CPDF_ModuleMgr::Get()->ReportError(FPDFERR_OUT_OF_MEMORY, str);
#else
		CPDF_ModuleMgr::Get()->ReportError(FPDFERR_OUT_OF_MEMORY, NULL);
#endif
	}
	FXSYS_memset(pBuffer, 0xff, height*((width*3+3)/4*4));

#ifdef DEBUG_TRACE
	{
		CPDF_ModuleMgr::Get()->ReportError(999, "DIBSection created");
	}
#endif

	// Create a device with this external buffer
	pContext->m_pBitmap = new CFX_DIBitmap;
	pContext->m_pBitmap->Create(width, height, FXDIB_Rgb, (uint8_t*)pBuffer);
	pContext->m_pDevice = new CPDF_FxgeDevice;
	((CPDF_FxgeDevice*)pContext->m_pDevice)->Attach(pContext->m_pBitmap);

#ifdef DEBUG_TRACE
	CPDF_ModuleMgr::Get()->ReportError(999, "Ready for PDF rendering");
#endif

	// output to bitmap device
	Func_RenderPage(pContext, page, start_x - rect.left, start_y - rect.top, size_x, size_y, rotate, flags);

#ifdef DEBUG_TRACE
	CPDF_ModuleMgr::Get()->ReportError(999, "Finished PDF rendering");
#endif

	// Now output to real device
	HDC hMemDC = CreateCompatibleDC(dc);
	if (hMemDC == NULL) {
#if defined(DEBUG) || defined(_DEBUG)
		char str[128];
		memset(str, 0, sizeof(str));
		FXSYS_snprintf(str, sizeof(str) - 1, "Error CreateCompatibleDC. Error code = %d", GetLastError());
		CPDF_ModuleMgr::Get()->ReportError(FPDFERR_OUT_OF_MEMORY, str);
#else
		CPDF_ModuleMgr::Get()->ReportError(FPDFERR_OUT_OF_MEMORY, NULL);
#endif
	}

	HGDIOBJ hOldBitmap = SelectObject(hMemDC, pContext->m_hBitmap);

#ifdef DEBUG_TRACE
	CPDF_ModuleMgr::Get()->ReportError(999, "Ready for screen rendering");
#endif

	BitBlt(dc, rect.left, rect.top, width, height, hMemDC, 0, 0, SRCCOPY);
	SelectObject(hMemDC, hOldBitmap);
	DeleteDC(hMemDC);

#ifdef DEBUG_TRACE
	CPDF_ModuleMgr::Get()->ReportError(999, "Finished screen rendering");
#endif

#endif
    if (bBackgroundAlphaNeeded) {
        delete pBitmap;
        pBitmap = NULL;
    }
    delete pContext;
    pPage->RemovePrivateData((void*)1);
}