| Index: xfa/src/fdp/src/fde/fde_gdidevice.cpp
|
| diff --git a/xfa/src/fdp/src/fde/fde_gdidevice.cpp b/xfa/src/fdp/src/fde/fde_gdidevice.cpp
|
| index 0035f6b866a5dadcdeb7f3cdbd43cdfaf35f762d..55b206e80c21447a321d11afa74bfd6b6caafe5b 100644
|
| --- a/xfa/src/fdp/src/fde/fde_gdidevice.cpp
|
| +++ b/xfa/src/fdp/src/fde/fde_gdidevice.cpp
|
| @@ -1,629 +1,629 @@
|
| -// Copyright 2014 PDFium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
|
| -
|
| -#include "stdafx.h"
|
| -#include "fde_gdidevice.h"
|
| -#include "fde_gdiobject.h"
|
| -#ifdef _FDEPLUS
|
| -#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN32_MOBILE_ || \
|
| - _FX_OS_ == _FX_WIN64_
|
| -IFDE_RenderDevice* IFDE_RenderDevice::Create(CFX_DIBitmap* pBitmap,
|
| - FX_BOOL bRgbByteOrder) {
|
| - return new CFDE_GdiDevice(pBitmap);
|
| -}
|
| -IFDE_RenderDevice* IFDE_RenderDevice::Create(CFX_RenderDevice* pDevice) {
|
| - return NULL;
|
| -}
|
| -CFDE_GdiDevice::CFDE_GdiDevice(CFX_DIBitmap* pBitmap)
|
| - : m_dwGlyphLen(0),
|
| - m_pGlyphBuf(NULL),
|
| - m_pGraphics(NULL),
|
| - m_pBitmap(NULL),
|
| - m_pClipPath(NULL) {
|
| - FXSYS_assert(pBitmap != NULL);
|
| - BITMAPINFO bmi;
|
| - FXSYS_memset(&bmi, 0, sizeof(BITMAPINFOHEADER));
|
| - bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
| - bmi.bmiHeader.biWidth = pBitmap->GetWidth();
|
| - bmi.bmiHeader.biHeight = -pBitmap->GetHeight();
|
| - bmi.bmiHeader.biPlanes = 1;
|
| - bmi.bmiHeader.biBitCount = pBitmap->GetBPP();
|
| - m_pBitmap = Gdiplus::Bitmap::FromBITMAPINFO(&bmi, pBitmap->GetBuffer());
|
| - FXSYS_assert(m_pBitmap != NULL);
|
| - m_pGraphics = Gdiplus::Graphics::FromImage(m_pBitmap);
|
| - FXSYS_assert(m_pGraphics != NULL);
|
| - m_rtClipRect.Set(0, 0, (FX_FLOAT)pBitmap->GetWidth(),
|
| - (FX_FLOAT)pBitmap->GetHeight());
|
| - m_pGraphics->SetClip((const Gdiplus::RectF&)m_rtClipRect);
|
| -}
|
| -CFDE_GdiDevice::~CFDE_GdiDevice() {
|
| - delete m_pGraphics;
|
| - delete m_pBitmap;
|
| - FX_Free(m_pGlyphBuf);
|
| -}
|
| -int32_t CFDE_GdiDevice::GetWidth() const {
|
| - return m_pBitmap->GetWidth();
|
| -}
|
| -int32_t CFDE_GdiDevice::GetHeight() const {
|
| - return m_pBitmap->GetHeight();
|
| -}
|
| -FDE_HDEVICESTATE CFDE_GdiDevice::SaveState() {
|
| - return (FDE_HDEVICESTATE)m_pGraphics->Save();
|
| -}
|
| -void CFDE_GdiDevice::RestoreState(FDE_HDEVICESTATE hState) {
|
| - Gdiplus::Status eRet = m_pGraphics->Restore((Gdiplus::GraphicsState)hState);
|
| - if (eRet == Gdiplus::Ok) {
|
| - Gdiplus::Rect rt;
|
| - eRet = m_pGraphics->GetClipBounds(&rt);
|
| - if (eRet == Gdiplus::Ok) {
|
| - m_rtClipRect.Set((FX_FLOAT)rt.X, (FX_FLOAT)rt.Y, (FX_FLOAT)rt.Width,
|
| - (FX_FLOAT)rt.Height);
|
| - }
|
| - }
|
| -}
|
| -FX_BOOL CFDE_GdiDevice::SetClipRect(const CFX_RectF& rtClip) {
|
| - m_rtClipRect = rtClip;
|
| - return m_pGraphics->SetClip((const Gdiplus::RectF&)rtClip) == Gdiplus::Ok;
|
| -}
|
| -const CFX_RectF& CFDE_GdiDevice::GetClipRect() {
|
| - return m_rtClipRect;
|
| -}
|
| -FX_BOOL CFDE_GdiDevice::SetClipPath(const IFDE_Path* pClip) {
|
| - m_pClipPath = (CFDE_GdiPath*)pClip;
|
| - Gdiplus::GraphicsPath* pPath = m_pClipPath ? &m_pClipPath->m_Path : NULL;
|
| - return m_pGraphics->SetClip(pPath) == Gdiplus::Ok;
|
| -}
|
| -IFDE_Path* CFDE_GdiDevice::GetClipPath() const {
|
| - return m_pClipPath;
|
| -}
|
| -FX_FLOAT CFDE_GdiDevice::GetDpiX() const {
|
| - return m_pGraphics->GetDpiX();
|
| -}
|
| -FX_FLOAT CFDE_GdiDevice::GetDpiY() const {
|
| - return m_pGraphics->GetDpiY();
|
| -}
|
| -FX_BOOL CFDE_GdiDevice::DrawImage(IFDE_Image* pImg,
|
| - const CFX_RectF* pSrcRect,
|
| - const CFX_RectF& dstRect,
|
| - const CFX_Matrix* pImgMatrix,
|
| - const CFX_Matrix* pDevMatrix) {
|
| - CFDE_GdiImage* pGdiImg = (CFDE_GdiImage*)pImg;
|
| - FXSYS_assert(pGdiImg != NULL && pGdiImg->m_pImage != NULL);
|
| - CFX_RectF srcRect;
|
| - if (pSrcRect) {
|
| - srcRect = *pSrcRect;
|
| - } else {
|
| - srcRect.left = srcRect.top = 0;
|
| - srcRect.width = (FX_FLOAT)pImg->GetImageWidth();
|
| - srcRect.height = (FX_FLOAT)pImg->GetImageHeight();
|
| - }
|
| - CFX_Matrix matrix;
|
| - if (pImgMatrix) {
|
| - matrix = *pImgMatrix;
|
| - } else {
|
| - matrix.Reset();
|
| - }
|
| - matrix.Translate(dstRect.left, dstRect.top);
|
| - matrix.Scale((dstRect.width / srcRect.width),
|
| - (dstRect.height / srcRect.height), TRUE);
|
| - if (pDevMatrix) {
|
| - matrix.Concat(*pDevMatrix);
|
| - }
|
| - CFX_PointF dstPoints[3];
|
| - dstPoints[0].Set(0, 0);
|
| - dstPoints[1].Set(srcRect.width, 0);
|
| - dstPoints[2].Set(0, srcRect.height);
|
| - matrix.TransformPoints(dstPoints, 3);
|
| - m_pGraphics->DrawImage(pGdiImg->m_pImage, (Gdiplus::PointF*)dstPoints, 3,
|
| - srcRect.left, srcRect.top, srcRect.width,
|
| - srcRect.height, Gdiplus::UnitPixel, NULL, NULL, NULL);
|
| - return TRUE;
|
| -}
|
| -FX_BOOL CFDE_GdiDevice::DrawImage(CFX_DIBSource* pDib,
|
| - const CFX_RectF* pSrcRect,
|
| - const CFX_RectF& dstRect,
|
| - const CFX_Matrix* pImgMatrix,
|
| - const CFX_Matrix* pDevMatrix) {
|
| - FXSYS_assert(pDib != NULL);
|
| - BITMAPINFO bmi;
|
| - FXSYS_memset(&bmi, 0, sizeof(BITMAPINFOHEADER));
|
| - bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
| - bmi.bmiHeader.biWidth = pDib->GetWidth();
|
| - bmi.bmiHeader.biHeight = pDib->GetHeight();
|
| - bmi.bmiHeader.biPlanes = 1;
|
| - bmi.bmiHeader.biBitCount = pDib->GetBPP();
|
| - Gdiplus::Bitmap bmp(&bmi, pDib->GetBuffer());
|
| - CFDE_GdiImage img(&bmp);
|
| - return DrawImage(&img, pSrcRect, dstRect, pImgMatrix, pDevMatrix);
|
| -}
|
| -FX_BOOL CFDE_GdiDevice::DrawString(IFDE_Brush* pBrush,
|
| - IFX_Font* pFont,
|
| - const FXTEXT_CHARPOS* pCharPos,
|
| - int32_t iCount,
|
| - FX_FLOAT fFontSize,
|
| - const CFX_Matrix* pMatrix) {
|
| - FXSYS_assert(pBrush != NULL && pFont != NULL && pCharPos != NULL);
|
| - FX_ARGB argb = 0xFF000000;
|
| - if (pBrush->GetType() == FDE_BRUSHTYPE_Solid) {
|
| - argb = ((IFDE_SolidBrush*)pBrush)->GetColor();
|
| - }
|
| - CFDE_GdiFont* pGdiFont = (CFDE_GdiFont*)pFont;
|
| - GLYPHMETRICS gm;
|
| - MAT2 mat2;
|
| - FX_FLOAT fScale = fFontSize / 1000.0f;
|
| - FX_FLOAT ma, mb, mc, md;
|
| - FX_FLOAT fx, fy;
|
| - while (--iCount >= 0) {
|
| - mb = mc = 0;
|
| - ma = md = fScale;
|
| - if (pCharPos->m_bGlyphAdjust) {
|
| - FX_FLOAT aa =
|
| - ma * -pCharPos->m_AdjustMatrix[0] + mb * pCharPos->m_AdjustMatrix[2];
|
| - FX_FLOAT bb =
|
| - -ma * pCharPos->m_AdjustMatrix[1] + mb * pCharPos->m_AdjustMatrix[3];
|
| - FX_FLOAT cc =
|
| - mc * -pCharPos->m_AdjustMatrix[0] + md * pCharPos->m_AdjustMatrix[2];
|
| - FX_FLOAT dd =
|
| - -mc * pCharPos->m_AdjustMatrix[1] + md * pCharPos->m_AdjustMatrix[3];
|
| - ma = aa;
|
| - mb = bb;
|
| - mc = cc;
|
| - md = dd;
|
| - }
|
| - if (pMatrix) {
|
| - FX_FLOAT aa = ma * pMatrix->a + mb * pMatrix->c;
|
| - FX_FLOAT bb = ma * pMatrix->b + mb * pMatrix->d;
|
| - FX_FLOAT cc = mc * pMatrix->a + md * pMatrix->c;
|
| - FX_FLOAT dd = mc * pMatrix->b + md * pMatrix->d;
|
| - ma = aa;
|
| - mb = bb;
|
| - mc = cc;
|
| - md = dd;
|
| - }
|
| - *(long*)(&mat2.eM11) = (long)(ma * 65536);
|
| - *(long*)(&mat2.eM21) = (long)(mb * 65536);
|
| - *(long*)(&mat2.eM12) = (long)(mc * 65536);
|
| - *(long*)(&mat2.eM22) = (long)(md * 65536);
|
| - FX_DWORD dwSize = pGdiFont->GetGlyphDIBits(pCharPos->m_GlyphIndex, argb,
|
| - &mat2, gm, NULL, 0);
|
| - if (dwSize > 0) {
|
| - if (m_pGlyphBuf == NULL) {
|
| - m_pGlyphBuf = FX_Alloc(uint8_t, dwSize);
|
| - m_dwGlyphLen = dwSize;
|
| - } else if (m_dwGlyphLen < dwSize) {
|
| - m_pGlyphBuf = FX_Realloc(uint8_t, m_pGlyphBuf, dwSize);
|
| - m_dwGlyphLen = dwSize;
|
| - }
|
| - pGdiFont->GetGlyphDIBits(pCharPos->m_GlyphIndex, argb, &mat2, gm,
|
| - m_pGlyphBuf, m_dwGlyphLen);
|
| - Gdiplus::Bitmap bmp(gm.gmBlackBoxX, gm.gmBlackBoxY, gm.gmBlackBoxX * 4,
|
| - PixelFormat32bppARGB, m_pGlyphBuf);
|
| - if (pMatrix) {
|
| - fx = pMatrix->a * pCharPos->m_OriginX +
|
| - pMatrix->c * pCharPos->m_OriginY + pMatrix->e;
|
| - fy = pMatrix->b * pCharPos->m_OriginX +
|
| - pMatrix->d * pCharPos->m_OriginY + pMatrix->f;
|
| - } else {
|
| - fx = pCharPos->m_OriginX;
|
| - fy = pCharPos->m_OriginY;
|
| - }
|
| - m_pGraphics->DrawImage(&bmp, (FXSYS_round(fx) + gm.gmptGlyphOrigin.x),
|
| - (FXSYS_round(fy) - gm.gmptGlyphOrigin.y));
|
| - }
|
| - pCharPos++;
|
| - }
|
| - return TRUE;
|
| -}
|
| -FX_BOOL CFDE_GdiDevice::DrawArc(IFDE_Pen* pPen,
|
| - FX_FLOAT fPenWidth,
|
| - const CFX_RectF& rect,
|
| - FX_FLOAT startAngle,
|
| - FX_FLOAT sweepAngle,
|
| - const CFX_Matrix* pMatrix) {
|
| - startAngle = FX_RAD2DEG(startAngle);
|
| - sweepAngle = FX_RAD2DEG(sweepAngle);
|
| - Gdiplus::Pen* pGdiPen = CreateGdiPen(pPen, fPenWidth);
|
| - if (pGdiPen == NULL) {
|
| - return FALSE;
|
| - }
|
| - ApplyMatrix(pMatrix);
|
| - Gdiplus::Status ret =
|
| - m_pGraphics->DrawArc(pGdiPen, rect.left, rect.top, rect.width,
|
| - rect.height, startAngle, sweepAngle);
|
| - RestoreMatrix(pMatrix);
|
| - ReleaseGdiPen(pGdiPen);
|
| - return ret == Gdiplus::Ok;
|
| -}
|
| -FX_BOOL CFDE_GdiDevice::DrawBezier(IFDE_Pen* pPen,
|
| - FX_FLOAT fPenWidth,
|
| - const CFX_PointF& pt1,
|
| - const CFX_PointF& pt2,
|
| - const CFX_PointF& pt3,
|
| - const CFX_PointF& pt4,
|
| - const CFX_Matrix* pMatrix) {
|
| - Gdiplus::Pen* pGdiPen = CreateGdiPen(pPen, fPenWidth);
|
| - if (pGdiPen == NULL) {
|
| - return FALSE;
|
| - }
|
| - ApplyMatrix(pMatrix);
|
| - Gdiplus::Status ret = m_pGraphics->DrawBezier(
|
| - pGdiPen, pt1.x, pt1.y, pt2.x, pt2.y, pt3.x, pt3.y, pt4.x, pt4.y);
|
| - RestoreMatrix(pMatrix);
|
| - ReleaseGdiPen(pGdiPen);
|
| - return ret == Gdiplus::Ok;
|
| -}
|
| -FX_BOOL CFDE_GdiDevice::DrawCurve(IFDE_Pen* pPen,
|
| - FX_FLOAT fPenWidth,
|
| - const CFX_PointsF& points,
|
| - FX_BOOL bClosed,
|
| - FX_FLOAT fTension,
|
| - const CFX_Matrix* pMatrix) {
|
| - Gdiplus::Pen* pGdiPen = CreateGdiPen(pPen, fPenWidth);
|
| - if (pGdiPen == NULL) {
|
| - return FALSE;
|
| - }
|
| - ApplyMatrix(pMatrix);
|
| - Gdiplus::Status ret =
|
| - bClosed
|
| - ? m_pGraphics->DrawClosedCurve(
|
| - pGdiPen, (const Gdiplus::PointF*)points.GetData(),
|
| - points.GetSize(), fTension)
|
| - : m_pGraphics->DrawCurve(pGdiPen,
|
| - (const Gdiplus::PointF*)points.GetData(),
|
| - points.GetSize(), fTension);
|
| - RestoreMatrix(pMatrix);
|
| - ReleaseGdiPen(pGdiPen);
|
| - return ret == Gdiplus::Ok;
|
| -}
|
| -FX_BOOL CFDE_GdiDevice::DrawEllipse(IFDE_Pen* pPen,
|
| - FX_FLOAT fPenWidth,
|
| - const CFX_RectF& rect,
|
| - const CFX_Matrix* pMatrix) {
|
| - Gdiplus::Pen* pGdiPen = CreateGdiPen(pPen, fPenWidth);
|
| - if (pGdiPen == NULL) {
|
| - return FALSE;
|
| - }
|
| - ApplyMatrix(pMatrix);
|
| - Gdiplus::Status ret = m_pGraphics->DrawEllipse(pGdiPen, rect.left, rect.top,
|
| - rect.width, rect.height);
|
| - RestoreMatrix(pMatrix);
|
| - ReleaseGdiPen(pGdiPen);
|
| - return ret == Gdiplus::Ok;
|
| -}
|
| -FX_BOOL CFDE_GdiDevice::DrawLines(IFDE_Pen* pPen,
|
| - FX_FLOAT fPenWidth,
|
| - const CFX_PointsF& points,
|
| - const CFX_Matrix* pMatrix) {
|
| - Gdiplus::Pen* pGdiPen = CreateGdiPen(pPen, fPenWidth);
|
| - if (pGdiPen == NULL) {
|
| - return FALSE;
|
| - }
|
| - ApplyMatrix(pMatrix);
|
| - Gdiplus::Status ret = m_pGraphics->DrawLines(
|
| - pGdiPen, (const Gdiplus::PointF*)points.GetData(), points.GetSize());
|
| - ApplyMatrix(pMatrix);
|
| - ReleaseGdiPen(pGdiPen);
|
| - return ret == Gdiplus::Ok;
|
| -}
|
| -FX_BOOL CFDE_GdiDevice::DrawLine(IFDE_Pen* pPen,
|
| - FX_FLOAT fPenWidth,
|
| - const CFX_PointF& pt1,
|
| - const CFX_PointF& pt2,
|
| - const CFX_Matrix* pMatrix) {
|
| - Gdiplus::Pen* pGdiPen = CreateGdiPen(pPen, fPenWidth);
|
| - if (pGdiPen == NULL) {
|
| - return FALSE;
|
| - }
|
| - ApplyMatrix(pMatrix);
|
| - Gdiplus::Status ret =
|
| - m_pGraphics->DrawLine(pGdiPen, pt1.x, pt1.y, pt2.x, pt2.y);
|
| - RestoreMatrix(pMatrix);
|
| - ReleaseGdiPen(pGdiPen);
|
| - return ret == Gdiplus::Ok;
|
| -}
|
| -FX_BOOL CFDE_GdiDevice::DrawPath(IFDE_Pen* pPen,
|
| - FX_FLOAT fPenWidth,
|
| - const IFDE_Path* pPath,
|
| - const CFX_Matrix* pMatrix) {
|
| - CFDE_GdiPath* pGdiPath = (CFDE_GdiPath*)pPath;
|
| - if (pGdiPath == NULL) {
|
| - return FALSE;
|
| - }
|
| - Gdiplus::Pen* pGdiPen = CreateGdiPen(pPen, fPenWidth);
|
| - if (pGdiPen == NULL) {
|
| - return FALSE;
|
| - }
|
| - ApplyMatrix(pMatrix);
|
| - Gdiplus::Status ret = m_pGraphics->DrawPath(pGdiPen, &pGdiPath->m_Path);
|
| - RestoreMatrix(pMatrix);
|
| - ReleaseGdiPen(pGdiPen);
|
| - return ret == Gdiplus::Ok;
|
| -}
|
| -FX_BOOL CFDE_GdiDevice::DrawPie(IFDE_Pen* pPen,
|
| - FX_FLOAT fPenWidth,
|
| - const CFX_RectF& rect,
|
| - FX_FLOAT startAngle,
|
| - FX_FLOAT sweepAngle,
|
| - const CFX_Matrix* pMatrix) {
|
| - startAngle = FX_RAD2DEG(startAngle);
|
| - sweepAngle = FX_RAD2DEG(sweepAngle);
|
| - Gdiplus::Pen* pGdiPen = CreateGdiPen(pPen, fPenWidth);
|
| - if (pGdiPen == NULL) {
|
| - return FALSE;
|
| - }
|
| - ApplyMatrix(pMatrix);
|
| - Gdiplus::Status ret =
|
| - m_pGraphics->DrawPie(pGdiPen, rect.left, rect.top, rect.width,
|
| - rect.height, startAngle, sweepAngle);
|
| - RestoreMatrix(pMatrix);
|
| - ReleaseGdiPen(pGdiPen);
|
| - return ret == Gdiplus::Ok;
|
| -}
|
| -FX_BOOL CFDE_GdiDevice::DrawChord(IFDE_Pen* pPen,
|
| - FX_FLOAT fPenWidth,
|
| - const CFX_RectF& rect,
|
| - FX_FLOAT startAngle,
|
| - FX_FLOAT sweepAngle,
|
| - const CFX_Matrix* pMatrix) {
|
| - CFX_ArcF chord;
|
| - chord.Set(rect, startAngle, sweepAngle);
|
| - CFDE_GdiPath path;
|
| - path.AddChord(chord);
|
| - return DrawPath(pPen, fPenWidth, &path, pMatrix);
|
| -}
|
| -FX_BOOL CFDE_GdiDevice::DrawPolygon(IFDE_Pen* pPen,
|
| - FX_FLOAT fPenWidth,
|
| - const CFX_PointsF& points,
|
| - const CFX_Matrix* pMatrix) {
|
| - Gdiplus::Pen* pGdiPen = CreateGdiPen(pPen, fPenWidth);
|
| - if (pGdiPen == NULL) {
|
| - return FALSE;
|
| - }
|
| - ApplyMatrix(pMatrix);
|
| - Gdiplus::Status ret = m_pGraphics->DrawPolygon(
|
| - pGdiPen, (const Gdiplus::PointF*)points.GetData(), points.GetSize());
|
| - RestoreMatrix(pMatrix);
|
| - ReleaseGdiPen(pGdiPen);
|
| - return ret == Gdiplus::Ok;
|
| -}
|
| -FX_BOOL CFDE_GdiDevice::DrawRectangle(IFDE_Pen* pPen,
|
| - FX_FLOAT fPenWidth,
|
| - const CFX_RectF& rect,
|
| - const CFX_Matrix* pMatrix) {
|
| - Gdiplus::Pen* pGdiPen = CreateGdiPen(pPen, fPenWidth);
|
| - if (pGdiPen == NULL) {
|
| - return FALSE;
|
| - }
|
| - ApplyMatrix(pMatrix);
|
| - Gdiplus::Status ret = m_pGraphics->DrawRectangle(pGdiPen, rect.left, rect.top,
|
| - rect.width, rect.height);
|
| - RestoreMatrix(pMatrix);
|
| - ReleaseGdiPen(pGdiPen);
|
| - return ret == Gdiplus::Ok;
|
| -}
|
| -FX_BOOL CFDE_GdiDevice::DrawRoundRectangle(IFDE_Pen* pPen,
|
| - FX_FLOAT fPenWidth,
|
| - const CFX_RectF& rect,
|
| - const CFX_SizeF& round,
|
| - const CFX_Matrix* pMatrix) {
|
| - CFDE_GdiPath path;
|
| - path.AddRoundRectangle(rect, round);
|
| - return DrawPath(pPen, fPenWidth, &path, pMatrix);
|
| -}
|
| -FX_BOOL CFDE_GdiDevice::FillClosedCurve(IFDE_Brush* pBrush,
|
| - const CFX_PointsF& points,
|
| - FX_FLOAT fTension,
|
| - const CFX_Matrix* pMatrix) {
|
| - Gdiplus::Brush* pGdiBrush = CreateGdiBrush(pBrush);
|
| - if (pGdiBrush == NULL) {
|
| - return FALSE;
|
| - }
|
| - ApplyMatrix(pMatrix);
|
| - Gdiplus::Status ret = m_pGraphics->FillClosedCurve(
|
| - pGdiBrush, (const Gdiplus::PointF*)points.GetData(), points.GetSize(),
|
| - Gdiplus::FillModeAlternate, fTension);
|
| - RestoreMatrix(pMatrix);
|
| - ReleaseGdiBrush(pGdiBrush);
|
| - return ret == Gdiplus::Ok;
|
| -}
|
| -FX_BOOL CFDE_GdiDevice::FillEllipse(IFDE_Brush* pBrush,
|
| - const CFX_RectF& rect,
|
| - const CFX_Matrix* pMatrix) {
|
| - Gdiplus::Brush* pGdiBrush = CreateGdiBrush(pBrush);
|
| - if (pGdiBrush == NULL) {
|
| - return FALSE;
|
| - }
|
| - ApplyMatrix(pMatrix);
|
| - Gdiplus::Status ret = m_pGraphics->FillEllipse(pGdiBrush, rect.left, rect.top,
|
| - rect.width, rect.height);
|
| - RestoreMatrix(pMatrix);
|
| - ReleaseGdiBrush(pGdiBrush);
|
| - return ret == Gdiplus::Ok;
|
| -}
|
| -FX_BOOL CFDE_GdiDevice::FillPath(IFDE_Brush* pBrush,
|
| - const IFDE_Path* pPath,
|
| - const CFX_Matrix* pMatrix) {
|
| - CFDE_GdiPath* pGdiPath = (CFDE_GdiPath*)pPath;
|
| - if (pGdiPath == NULL) {
|
| - return FALSE;
|
| - }
|
| - Gdiplus::Brush* pGdiBrush = CreateGdiBrush(pBrush);
|
| - if (pGdiBrush == NULL) {
|
| - return FALSE;
|
| - }
|
| - ApplyMatrix(pMatrix);
|
| - Gdiplus::Status ret = m_pGraphics->FillPath(pGdiBrush, &pGdiPath->m_Path);
|
| - RestoreMatrix(pMatrix);
|
| - ReleaseGdiBrush(pGdiBrush);
|
| - return ret == Gdiplus::Ok;
|
| -}
|
| -FX_BOOL CFDE_GdiDevice::FillPie(IFDE_Brush* pBrush,
|
| - const CFX_RectF& rect,
|
| - FX_FLOAT startAngle,
|
| - FX_FLOAT sweepAngle,
|
| - const CFX_Matrix* pMatrix) {
|
| - startAngle = FX_RAD2DEG(startAngle);
|
| - sweepAngle = FX_RAD2DEG(sweepAngle);
|
| - Gdiplus::Brush* pGdiBrush = CreateGdiBrush(pBrush);
|
| - if (pGdiBrush == NULL) {
|
| - return FALSE;
|
| - }
|
| - ApplyMatrix(pMatrix);
|
| - Gdiplus::Status ret =
|
| - m_pGraphics->FillPie(pGdiBrush, rect.left, rect.top, rect.width,
|
| - rect.height, startAngle, sweepAngle);
|
| - RestoreMatrix(pMatrix);
|
| - ReleaseGdiBrush(pGdiBrush);
|
| - return ret == Gdiplus::Ok;
|
| -}
|
| -FX_BOOL CFDE_GdiDevice::FillChord(IFDE_Brush* pBrush,
|
| - const CFX_RectF& rect,
|
| - FX_FLOAT startAngle,
|
| - FX_FLOAT sweepAngle,
|
| - const CFX_Matrix* pMatrix) {
|
| - CFX_ArcF chord;
|
| - chord.Set(rect, startAngle, sweepAngle);
|
| - CFDE_GdiPath path;
|
| - path.AddChord(chord);
|
| - return FillPath(pBrush, &path, pMatrix);
|
| -}
|
| -FX_BOOL CFDE_GdiDevice::FillPolygon(IFDE_Brush* pBrush,
|
| - const CFX_PointsF& points,
|
| - const CFX_Matrix* pMatrix) {
|
| - Gdiplus::Brush* pGdiBrush = CreateGdiBrush(pBrush);
|
| - if (pGdiBrush == NULL) {
|
| - return FALSE;
|
| - }
|
| - ApplyMatrix(pMatrix);
|
| - Gdiplus::Status ret = m_pGraphics->FillPolygon(
|
| - pGdiBrush, (const Gdiplus::PointF*)points.GetData(), points.GetSize());
|
| - RestoreMatrix(pMatrix);
|
| - ReleaseGdiBrush(pGdiBrush);
|
| - return ret == Gdiplus::Ok;
|
| -}
|
| -FX_BOOL CFDE_GdiDevice::FillRectangle(IFDE_Brush* pBrush,
|
| - const CFX_RectF& rect,
|
| - const CFX_Matrix* pMatrix) {
|
| - Gdiplus::Brush* pGdiBrush = CreateGdiBrush(pBrush);
|
| - if (pGdiBrush == NULL) {
|
| - return FALSE;
|
| - }
|
| - ApplyMatrix(pMatrix);
|
| - Gdiplus::Status ret = m_pGraphics->FillRectangle(
|
| - pGdiBrush, rect.left, rect.top, rect.width, rect.height);
|
| - RestoreMatrix(pMatrix);
|
| - ReleaseGdiBrush(pGdiBrush);
|
| - return ret == Gdiplus::Ok;
|
| -}
|
| -FX_BOOL CFDE_GdiDevice::FillRoundRectangle(IFDE_Brush* pBrush,
|
| - const CFX_RectF& rect,
|
| - const CFX_SizeF& round,
|
| - const CFX_Matrix* pMatrix) {
|
| - CFDE_GdiPath path;
|
| - path.AddRoundRectangle(rect, round);
|
| - return FillPath(pBrush, &path, pMatrix);
|
| -}
|
| -Gdiplus::Pen* CFDE_GdiDevice::CreateGdiPen(IFDE_Pen* pPen, FX_FLOAT fPenWidth) {
|
| - if (pPen == NULL || fPenWidth < 0.01f) {
|
| - return NULL;
|
| - }
|
| - Gdiplus::Pen* pGdiPen = NULL;
|
| - switch (pPen->GetType()) {
|
| - case FDE_PENTYPE_SolidColor: {
|
| - Gdiplus::Color gdiColor((Gdiplus::ARGB)pPen->GetColor());
|
| - pGdiPen = new Gdiplus::Pen(gdiColor, fPenWidth);
|
| - } break;
|
| - case FDE_PENTYPE_HatchBrush:
|
| - case FDE_PENTYPE_TextureBrush:
|
| - case FDE_PENTYPE_LinearGradient: {
|
| - Gdiplus::Brush* pGdiBrush = CreateGdiBrush(pPen->GetBrush());
|
| - if (pGdiBrush) {
|
| - pGdiPen = new Gdiplus::Pen(pGdiBrush, fPenWidth);
|
| - }
|
| - } break;
|
| - }
|
| - if (pGdiPen) {
|
| - CFX_FloatArray dashArray;
|
| - pPen->GetDashArray(dashArray);
|
| - pGdiPen->SetDashPattern(dashArray.GetData(), dashArray.GetSize());
|
| - pGdiPen->SetDashOffset(pPen->GetDashPhase());
|
| - pGdiPen->SetDashStyle((Gdiplus::DashStyle)pPen->GetDashStyle());
|
| - pGdiPen->SetStartCap((Gdiplus::LineCap)pPen->GetLineCap());
|
| - pGdiPen->SetEndCap((Gdiplus::LineCap)pPen->GetLineCap());
|
| - pGdiPen->SetLineJoin((Gdiplus::LineJoin)pPen->GetLineJoin());
|
| - pGdiPen->SetMiterLimit(pPen->GetMiterLimit());
|
| - }
|
| - return pGdiPen;
|
| -}
|
| -void CFDE_GdiDevice::ReleaseGdiPen(Gdiplus::Pen* pGdiPen) {
|
| - if (pGdiPen) {
|
| - ReleaseGdiBrush(pGdiPen->GetBrush());
|
| - delete pGdiPen;
|
| - }
|
| -}
|
| -Gdiplus::Brush* CFDE_GdiDevice::CreateGdiBrush(IFDE_Brush* pBrush) {
|
| - if (pBrush == NULL) {
|
| - return NULL;
|
| - }
|
| - Gdiplus::Brush* pGdiBrush = NULL;
|
| - switch (pBrush->GetType()) {
|
| - case FDE_BRUSHTYPE_Solid: {
|
| - IFDE_SolidBrush* pSolidBrush = (IFDE_SolidBrush*)pBrush;
|
| - Gdiplus::Color gdiColor((Gdiplus::ARGB)pSolidBrush->GetColor());
|
| - pGdiBrush = new Gdiplus::SolidBrush(gdiColor);
|
| - } break;
|
| - case FDE_BRUSHTYPE_Hatch: {
|
| - IFDE_HatchBrush* pHatchBrush = (IFDE_HatchBrush*)pBrush;
|
| - Gdiplus::Color foreColor((Gdiplus::ARGB)pHatchBrush->GetColor(TRUE));
|
| - Gdiplus::Color backColor((Gdiplus::ARGB)pHatchBrush->GetColor(FALSE));
|
| - Gdiplus::HatchStyle hatchStyle =
|
| - (Gdiplus::HatchStyle)pHatchBrush->GetHatchStyle();
|
| - pGdiBrush = new Gdiplus::HatchBrush(hatchStyle, foreColor, backColor);
|
| - } break;
|
| - case FDE_BRUSHTYPE_Texture: {
|
| - IFDE_TextureBrush* pTextureBrush = (IFDE_TextureBrush*)pBrush;
|
| - CFDE_GdiImage* pImgHolder = (CFDE_GdiImage*)pTextureBrush->GetImage();
|
| - Gdiplus::Image* pGdiImage = pImgHolder ? pImgHolder->m_pImage : NULL;
|
| - Gdiplus::WrapMode wrapMode =
|
| - (Gdiplus::WrapMode)pTextureBrush->GetWrapMode();
|
| - pGdiBrush = new Gdiplus::TextureBrush(pGdiImage, wrapMode);
|
| - } break;
|
| - case FDE_BRUSHTYPE_LinearGradient: {
|
| - IFDE_LinearGradientBrush* pLinearBrush =
|
| - (IFDE_LinearGradientBrush*)pBrush;
|
| - Gdiplus::WrapMode wrapMode =
|
| - (Gdiplus::WrapMode)pLinearBrush->GetWrapMode();
|
| - CFX_PointF ptStart, ptEnd;
|
| - pLinearBrush->GetLinearPoints(ptStart, ptEnd);
|
| - FX_ARGB crStart, crEnd;
|
| - pLinearBrush->GetLinearColors(crStart, crEnd);
|
| - pGdiBrush = new Gdiplus::LinearGradientBrush(
|
| - (const Gdiplus::PointF&)ptStart, (const Gdiplus::PointF&)ptEnd,
|
| - (const Gdiplus::Color&)crStart, (const Gdiplus::Color&)crEnd);
|
| - } break;
|
| - }
|
| - return pGdiBrush;
|
| -}
|
| -void CFDE_GdiDevice::ReleaseGdiBrush(Gdiplus::Brush* pGdiBrush) {
|
| - if (pGdiBrush) {
|
| - delete pGdiBrush;
|
| - }
|
| -}
|
| -void CFDE_GdiDevice::ApplyMatrix(const CFX_Matrix* pMatrix) {
|
| - if (pMatrix) {
|
| - m_GraphicsState = m_pGraphics->Save();
|
| - Gdiplus::Matrix gdiMatrix(pMatrix->a, pMatrix->b, pMatrix->c, pMatrix->d,
|
| - pMatrix->e, pMatrix->f);
|
| - m_pGraphics->SetTransform(&gdiMatrix);
|
| - }
|
| -}
|
| -void CFDE_GdiDevice::RestoreMatrix(const CFX_Matrix* pMatrix) {
|
| - if (pMatrix) {
|
| - m_pGraphics->Restore(m_GraphicsState);
|
| - }
|
| -}
|
| -#endif
|
| -#endif
|
| +// Copyright 2014 PDFium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
|
| +
|
| +#include "stdafx.h"
|
| +#include "fde_gdidevice.h"
|
| +#include "fde_gdiobject.h"
|
| +#ifdef _FDEPLUS
|
| +#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN32_MOBILE_ || \
|
| + _FX_OS_ == _FX_WIN64_
|
| +IFDE_RenderDevice* IFDE_RenderDevice::Create(CFX_DIBitmap* pBitmap,
|
| + FX_BOOL bRgbByteOrder) {
|
| + return new CFDE_GdiDevice(pBitmap);
|
| +}
|
| +IFDE_RenderDevice* IFDE_RenderDevice::Create(CFX_RenderDevice* pDevice) {
|
| + return NULL;
|
| +}
|
| +CFDE_GdiDevice::CFDE_GdiDevice(CFX_DIBitmap* pBitmap)
|
| + : m_dwGlyphLen(0),
|
| + m_pGlyphBuf(NULL),
|
| + m_pGraphics(NULL),
|
| + m_pBitmap(NULL),
|
| + m_pClipPath(NULL) {
|
| + FXSYS_assert(pBitmap != NULL);
|
| + BITMAPINFO bmi;
|
| + FXSYS_memset(&bmi, 0, sizeof(BITMAPINFOHEADER));
|
| + bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
| + bmi.bmiHeader.biWidth = pBitmap->GetWidth();
|
| + bmi.bmiHeader.biHeight = -pBitmap->GetHeight();
|
| + bmi.bmiHeader.biPlanes = 1;
|
| + bmi.bmiHeader.biBitCount = pBitmap->GetBPP();
|
| + m_pBitmap = Gdiplus::Bitmap::FromBITMAPINFO(&bmi, pBitmap->GetBuffer());
|
| + FXSYS_assert(m_pBitmap != NULL);
|
| + m_pGraphics = Gdiplus::Graphics::FromImage(m_pBitmap);
|
| + FXSYS_assert(m_pGraphics != NULL);
|
| + m_rtClipRect.Set(0, 0, (FX_FLOAT)pBitmap->GetWidth(),
|
| + (FX_FLOAT)pBitmap->GetHeight());
|
| + m_pGraphics->SetClip((const Gdiplus::RectF&)m_rtClipRect);
|
| +}
|
| +CFDE_GdiDevice::~CFDE_GdiDevice() {
|
| + delete m_pGraphics;
|
| + delete m_pBitmap;
|
| + FX_Free(m_pGlyphBuf);
|
| +}
|
| +int32_t CFDE_GdiDevice::GetWidth() const {
|
| + return m_pBitmap->GetWidth();
|
| +}
|
| +int32_t CFDE_GdiDevice::GetHeight() const {
|
| + return m_pBitmap->GetHeight();
|
| +}
|
| +FDE_HDEVICESTATE CFDE_GdiDevice::SaveState() {
|
| + return (FDE_HDEVICESTATE)m_pGraphics->Save();
|
| +}
|
| +void CFDE_GdiDevice::RestoreState(FDE_HDEVICESTATE hState) {
|
| + Gdiplus::Status eRet = m_pGraphics->Restore((Gdiplus::GraphicsState)hState);
|
| + if (eRet == Gdiplus::Ok) {
|
| + Gdiplus::Rect rt;
|
| + eRet = m_pGraphics->GetClipBounds(&rt);
|
| + if (eRet == Gdiplus::Ok) {
|
| + m_rtClipRect.Set((FX_FLOAT)rt.X, (FX_FLOAT)rt.Y, (FX_FLOAT)rt.Width,
|
| + (FX_FLOAT)rt.Height);
|
| + }
|
| + }
|
| +}
|
| +FX_BOOL CFDE_GdiDevice::SetClipRect(const CFX_RectF& rtClip) {
|
| + m_rtClipRect = rtClip;
|
| + return m_pGraphics->SetClip((const Gdiplus::RectF&)rtClip) == Gdiplus::Ok;
|
| +}
|
| +const CFX_RectF& CFDE_GdiDevice::GetClipRect() {
|
| + return m_rtClipRect;
|
| +}
|
| +FX_BOOL CFDE_GdiDevice::SetClipPath(const IFDE_Path* pClip) {
|
| + m_pClipPath = (CFDE_GdiPath*)pClip;
|
| + Gdiplus::GraphicsPath* pPath = m_pClipPath ? &m_pClipPath->m_Path : NULL;
|
| + return m_pGraphics->SetClip(pPath) == Gdiplus::Ok;
|
| +}
|
| +IFDE_Path* CFDE_GdiDevice::GetClipPath() const {
|
| + return m_pClipPath;
|
| +}
|
| +FX_FLOAT CFDE_GdiDevice::GetDpiX() const {
|
| + return m_pGraphics->GetDpiX();
|
| +}
|
| +FX_FLOAT CFDE_GdiDevice::GetDpiY() const {
|
| + return m_pGraphics->GetDpiY();
|
| +}
|
| +FX_BOOL CFDE_GdiDevice::DrawImage(IFDE_Image* pImg,
|
| + const CFX_RectF* pSrcRect,
|
| + const CFX_RectF& dstRect,
|
| + const CFX_Matrix* pImgMatrix,
|
| + const CFX_Matrix* pDevMatrix) {
|
| + CFDE_GdiImage* pGdiImg = (CFDE_GdiImage*)pImg;
|
| + FXSYS_assert(pGdiImg != NULL && pGdiImg->m_pImage != NULL);
|
| + CFX_RectF srcRect;
|
| + if (pSrcRect) {
|
| + srcRect = *pSrcRect;
|
| + } else {
|
| + srcRect.left = srcRect.top = 0;
|
| + srcRect.width = (FX_FLOAT)pImg->GetImageWidth();
|
| + srcRect.height = (FX_FLOAT)pImg->GetImageHeight();
|
| + }
|
| + CFX_Matrix matrix;
|
| + if (pImgMatrix) {
|
| + matrix = *pImgMatrix;
|
| + } else {
|
| + matrix.Reset();
|
| + }
|
| + matrix.Translate(dstRect.left, dstRect.top);
|
| + matrix.Scale((dstRect.width / srcRect.width),
|
| + (dstRect.height / srcRect.height), TRUE);
|
| + if (pDevMatrix) {
|
| + matrix.Concat(*pDevMatrix);
|
| + }
|
| + CFX_PointF dstPoints[3];
|
| + dstPoints[0].Set(0, 0);
|
| + dstPoints[1].Set(srcRect.width, 0);
|
| + dstPoints[2].Set(0, srcRect.height);
|
| + matrix.TransformPoints(dstPoints, 3);
|
| + m_pGraphics->DrawImage(pGdiImg->m_pImage, (Gdiplus::PointF*)dstPoints, 3,
|
| + srcRect.left, srcRect.top, srcRect.width,
|
| + srcRect.height, Gdiplus::UnitPixel, NULL, NULL, NULL);
|
| + return TRUE;
|
| +}
|
| +FX_BOOL CFDE_GdiDevice::DrawImage(CFX_DIBSource* pDib,
|
| + const CFX_RectF* pSrcRect,
|
| + const CFX_RectF& dstRect,
|
| + const CFX_Matrix* pImgMatrix,
|
| + const CFX_Matrix* pDevMatrix) {
|
| + FXSYS_assert(pDib != NULL);
|
| + BITMAPINFO bmi;
|
| + FXSYS_memset(&bmi, 0, sizeof(BITMAPINFOHEADER));
|
| + bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
| + bmi.bmiHeader.biWidth = pDib->GetWidth();
|
| + bmi.bmiHeader.biHeight = pDib->GetHeight();
|
| + bmi.bmiHeader.biPlanes = 1;
|
| + bmi.bmiHeader.biBitCount = pDib->GetBPP();
|
| + Gdiplus::Bitmap bmp(&bmi, pDib->GetBuffer());
|
| + CFDE_GdiImage img(&bmp);
|
| + return DrawImage(&img, pSrcRect, dstRect, pImgMatrix, pDevMatrix);
|
| +}
|
| +FX_BOOL CFDE_GdiDevice::DrawString(IFDE_Brush* pBrush,
|
| + IFX_Font* pFont,
|
| + const FXTEXT_CHARPOS* pCharPos,
|
| + int32_t iCount,
|
| + FX_FLOAT fFontSize,
|
| + const CFX_Matrix* pMatrix) {
|
| + FXSYS_assert(pBrush != NULL && pFont != NULL && pCharPos != NULL);
|
| + FX_ARGB argb = 0xFF000000;
|
| + if (pBrush->GetType() == FDE_BRUSHTYPE_Solid) {
|
| + argb = ((IFDE_SolidBrush*)pBrush)->GetColor();
|
| + }
|
| + CFDE_GdiFont* pGdiFont = (CFDE_GdiFont*)pFont;
|
| + GLYPHMETRICS gm;
|
| + MAT2 mat2;
|
| + FX_FLOAT fScale = fFontSize / 1000.0f;
|
| + FX_FLOAT ma, mb, mc, md;
|
| + FX_FLOAT fx, fy;
|
| + while (--iCount >= 0) {
|
| + mb = mc = 0;
|
| + ma = md = fScale;
|
| + if (pCharPos->m_bGlyphAdjust) {
|
| + FX_FLOAT aa =
|
| + ma * -pCharPos->m_AdjustMatrix[0] + mb * pCharPos->m_AdjustMatrix[2];
|
| + FX_FLOAT bb =
|
| + -ma * pCharPos->m_AdjustMatrix[1] + mb * pCharPos->m_AdjustMatrix[3];
|
| + FX_FLOAT cc =
|
| + mc * -pCharPos->m_AdjustMatrix[0] + md * pCharPos->m_AdjustMatrix[2];
|
| + FX_FLOAT dd =
|
| + -mc * pCharPos->m_AdjustMatrix[1] + md * pCharPos->m_AdjustMatrix[3];
|
| + ma = aa;
|
| + mb = bb;
|
| + mc = cc;
|
| + md = dd;
|
| + }
|
| + if (pMatrix) {
|
| + FX_FLOAT aa = ma * pMatrix->a + mb * pMatrix->c;
|
| + FX_FLOAT bb = ma * pMatrix->b + mb * pMatrix->d;
|
| + FX_FLOAT cc = mc * pMatrix->a + md * pMatrix->c;
|
| + FX_FLOAT dd = mc * pMatrix->b + md * pMatrix->d;
|
| + ma = aa;
|
| + mb = bb;
|
| + mc = cc;
|
| + md = dd;
|
| + }
|
| + *(long*)(&mat2.eM11) = (long)(ma * 65536);
|
| + *(long*)(&mat2.eM21) = (long)(mb * 65536);
|
| + *(long*)(&mat2.eM12) = (long)(mc * 65536);
|
| + *(long*)(&mat2.eM22) = (long)(md * 65536);
|
| + FX_DWORD dwSize = pGdiFont->GetGlyphDIBits(pCharPos->m_GlyphIndex, argb,
|
| + &mat2, gm, NULL, 0);
|
| + if (dwSize > 0) {
|
| + if (m_pGlyphBuf == NULL) {
|
| + m_pGlyphBuf = FX_Alloc(uint8_t, dwSize);
|
| + m_dwGlyphLen = dwSize;
|
| + } else if (m_dwGlyphLen < dwSize) {
|
| + m_pGlyphBuf = FX_Realloc(uint8_t, m_pGlyphBuf, dwSize);
|
| + m_dwGlyphLen = dwSize;
|
| + }
|
| + pGdiFont->GetGlyphDIBits(pCharPos->m_GlyphIndex, argb, &mat2, gm,
|
| + m_pGlyphBuf, m_dwGlyphLen);
|
| + Gdiplus::Bitmap bmp(gm.gmBlackBoxX, gm.gmBlackBoxY, gm.gmBlackBoxX * 4,
|
| + PixelFormat32bppARGB, m_pGlyphBuf);
|
| + if (pMatrix) {
|
| + fx = pMatrix->a * pCharPos->m_OriginX +
|
| + pMatrix->c * pCharPos->m_OriginY + pMatrix->e;
|
| + fy = pMatrix->b * pCharPos->m_OriginX +
|
| + pMatrix->d * pCharPos->m_OriginY + pMatrix->f;
|
| + } else {
|
| + fx = pCharPos->m_OriginX;
|
| + fy = pCharPos->m_OriginY;
|
| + }
|
| + m_pGraphics->DrawImage(&bmp, (FXSYS_round(fx) + gm.gmptGlyphOrigin.x),
|
| + (FXSYS_round(fy) - gm.gmptGlyphOrigin.y));
|
| + }
|
| + pCharPos++;
|
| + }
|
| + return TRUE;
|
| +}
|
| +FX_BOOL CFDE_GdiDevice::DrawArc(IFDE_Pen* pPen,
|
| + FX_FLOAT fPenWidth,
|
| + const CFX_RectF& rect,
|
| + FX_FLOAT startAngle,
|
| + FX_FLOAT sweepAngle,
|
| + const CFX_Matrix* pMatrix) {
|
| + startAngle = FX_RAD2DEG(startAngle);
|
| + sweepAngle = FX_RAD2DEG(sweepAngle);
|
| + Gdiplus::Pen* pGdiPen = CreateGdiPen(pPen, fPenWidth);
|
| + if (pGdiPen == NULL) {
|
| + return FALSE;
|
| + }
|
| + ApplyMatrix(pMatrix);
|
| + Gdiplus::Status ret =
|
| + m_pGraphics->DrawArc(pGdiPen, rect.left, rect.top, rect.width,
|
| + rect.height, startAngle, sweepAngle);
|
| + RestoreMatrix(pMatrix);
|
| + ReleaseGdiPen(pGdiPen);
|
| + return ret == Gdiplus::Ok;
|
| +}
|
| +FX_BOOL CFDE_GdiDevice::DrawBezier(IFDE_Pen* pPen,
|
| + FX_FLOAT fPenWidth,
|
| + const CFX_PointF& pt1,
|
| + const CFX_PointF& pt2,
|
| + const CFX_PointF& pt3,
|
| + const CFX_PointF& pt4,
|
| + const CFX_Matrix* pMatrix) {
|
| + Gdiplus::Pen* pGdiPen = CreateGdiPen(pPen, fPenWidth);
|
| + if (pGdiPen == NULL) {
|
| + return FALSE;
|
| + }
|
| + ApplyMatrix(pMatrix);
|
| + Gdiplus::Status ret = m_pGraphics->DrawBezier(
|
| + pGdiPen, pt1.x, pt1.y, pt2.x, pt2.y, pt3.x, pt3.y, pt4.x, pt4.y);
|
| + RestoreMatrix(pMatrix);
|
| + ReleaseGdiPen(pGdiPen);
|
| + return ret == Gdiplus::Ok;
|
| +}
|
| +FX_BOOL CFDE_GdiDevice::DrawCurve(IFDE_Pen* pPen,
|
| + FX_FLOAT fPenWidth,
|
| + const CFX_PointsF& points,
|
| + FX_BOOL bClosed,
|
| + FX_FLOAT fTension,
|
| + const CFX_Matrix* pMatrix) {
|
| + Gdiplus::Pen* pGdiPen = CreateGdiPen(pPen, fPenWidth);
|
| + if (pGdiPen == NULL) {
|
| + return FALSE;
|
| + }
|
| + ApplyMatrix(pMatrix);
|
| + Gdiplus::Status ret =
|
| + bClosed
|
| + ? m_pGraphics->DrawClosedCurve(
|
| + pGdiPen, (const Gdiplus::PointF*)points.GetData(),
|
| + points.GetSize(), fTension)
|
| + : m_pGraphics->DrawCurve(pGdiPen,
|
| + (const Gdiplus::PointF*)points.GetData(),
|
| + points.GetSize(), fTension);
|
| + RestoreMatrix(pMatrix);
|
| + ReleaseGdiPen(pGdiPen);
|
| + return ret == Gdiplus::Ok;
|
| +}
|
| +FX_BOOL CFDE_GdiDevice::DrawEllipse(IFDE_Pen* pPen,
|
| + FX_FLOAT fPenWidth,
|
| + const CFX_RectF& rect,
|
| + const CFX_Matrix* pMatrix) {
|
| + Gdiplus::Pen* pGdiPen = CreateGdiPen(pPen, fPenWidth);
|
| + if (pGdiPen == NULL) {
|
| + return FALSE;
|
| + }
|
| + ApplyMatrix(pMatrix);
|
| + Gdiplus::Status ret = m_pGraphics->DrawEllipse(pGdiPen, rect.left, rect.top,
|
| + rect.width, rect.height);
|
| + RestoreMatrix(pMatrix);
|
| + ReleaseGdiPen(pGdiPen);
|
| + return ret == Gdiplus::Ok;
|
| +}
|
| +FX_BOOL CFDE_GdiDevice::DrawLines(IFDE_Pen* pPen,
|
| + FX_FLOAT fPenWidth,
|
| + const CFX_PointsF& points,
|
| + const CFX_Matrix* pMatrix) {
|
| + Gdiplus::Pen* pGdiPen = CreateGdiPen(pPen, fPenWidth);
|
| + if (pGdiPen == NULL) {
|
| + return FALSE;
|
| + }
|
| + ApplyMatrix(pMatrix);
|
| + Gdiplus::Status ret = m_pGraphics->DrawLines(
|
| + pGdiPen, (const Gdiplus::PointF*)points.GetData(), points.GetSize());
|
| + ApplyMatrix(pMatrix);
|
| + ReleaseGdiPen(pGdiPen);
|
| + return ret == Gdiplus::Ok;
|
| +}
|
| +FX_BOOL CFDE_GdiDevice::DrawLine(IFDE_Pen* pPen,
|
| + FX_FLOAT fPenWidth,
|
| + const CFX_PointF& pt1,
|
| + const CFX_PointF& pt2,
|
| + const CFX_Matrix* pMatrix) {
|
| + Gdiplus::Pen* pGdiPen = CreateGdiPen(pPen, fPenWidth);
|
| + if (pGdiPen == NULL) {
|
| + return FALSE;
|
| + }
|
| + ApplyMatrix(pMatrix);
|
| + Gdiplus::Status ret =
|
| + m_pGraphics->DrawLine(pGdiPen, pt1.x, pt1.y, pt2.x, pt2.y);
|
| + RestoreMatrix(pMatrix);
|
| + ReleaseGdiPen(pGdiPen);
|
| + return ret == Gdiplus::Ok;
|
| +}
|
| +FX_BOOL CFDE_GdiDevice::DrawPath(IFDE_Pen* pPen,
|
| + FX_FLOAT fPenWidth,
|
| + const IFDE_Path* pPath,
|
| + const CFX_Matrix* pMatrix) {
|
| + CFDE_GdiPath* pGdiPath = (CFDE_GdiPath*)pPath;
|
| + if (pGdiPath == NULL) {
|
| + return FALSE;
|
| + }
|
| + Gdiplus::Pen* pGdiPen = CreateGdiPen(pPen, fPenWidth);
|
| + if (pGdiPen == NULL) {
|
| + return FALSE;
|
| + }
|
| + ApplyMatrix(pMatrix);
|
| + Gdiplus::Status ret = m_pGraphics->DrawPath(pGdiPen, &pGdiPath->m_Path);
|
| + RestoreMatrix(pMatrix);
|
| + ReleaseGdiPen(pGdiPen);
|
| + return ret == Gdiplus::Ok;
|
| +}
|
| +FX_BOOL CFDE_GdiDevice::DrawPie(IFDE_Pen* pPen,
|
| + FX_FLOAT fPenWidth,
|
| + const CFX_RectF& rect,
|
| + FX_FLOAT startAngle,
|
| + FX_FLOAT sweepAngle,
|
| + const CFX_Matrix* pMatrix) {
|
| + startAngle = FX_RAD2DEG(startAngle);
|
| + sweepAngle = FX_RAD2DEG(sweepAngle);
|
| + Gdiplus::Pen* pGdiPen = CreateGdiPen(pPen, fPenWidth);
|
| + if (pGdiPen == NULL) {
|
| + return FALSE;
|
| + }
|
| + ApplyMatrix(pMatrix);
|
| + Gdiplus::Status ret =
|
| + m_pGraphics->DrawPie(pGdiPen, rect.left, rect.top, rect.width,
|
| + rect.height, startAngle, sweepAngle);
|
| + RestoreMatrix(pMatrix);
|
| + ReleaseGdiPen(pGdiPen);
|
| + return ret == Gdiplus::Ok;
|
| +}
|
| +FX_BOOL CFDE_GdiDevice::DrawChord(IFDE_Pen* pPen,
|
| + FX_FLOAT fPenWidth,
|
| + const CFX_RectF& rect,
|
| + FX_FLOAT startAngle,
|
| + FX_FLOAT sweepAngle,
|
| + const CFX_Matrix* pMatrix) {
|
| + CFX_ArcF chord;
|
| + chord.Set(rect, startAngle, sweepAngle);
|
| + CFDE_GdiPath path;
|
| + path.AddChord(chord);
|
| + return DrawPath(pPen, fPenWidth, &path, pMatrix);
|
| +}
|
| +FX_BOOL CFDE_GdiDevice::DrawPolygon(IFDE_Pen* pPen,
|
| + FX_FLOAT fPenWidth,
|
| + const CFX_PointsF& points,
|
| + const CFX_Matrix* pMatrix) {
|
| + Gdiplus::Pen* pGdiPen = CreateGdiPen(pPen, fPenWidth);
|
| + if (pGdiPen == NULL) {
|
| + return FALSE;
|
| + }
|
| + ApplyMatrix(pMatrix);
|
| + Gdiplus::Status ret = m_pGraphics->DrawPolygon(
|
| + pGdiPen, (const Gdiplus::PointF*)points.GetData(), points.GetSize());
|
| + RestoreMatrix(pMatrix);
|
| + ReleaseGdiPen(pGdiPen);
|
| + return ret == Gdiplus::Ok;
|
| +}
|
| +FX_BOOL CFDE_GdiDevice::DrawRectangle(IFDE_Pen* pPen,
|
| + FX_FLOAT fPenWidth,
|
| + const CFX_RectF& rect,
|
| + const CFX_Matrix* pMatrix) {
|
| + Gdiplus::Pen* pGdiPen = CreateGdiPen(pPen, fPenWidth);
|
| + if (pGdiPen == NULL) {
|
| + return FALSE;
|
| + }
|
| + ApplyMatrix(pMatrix);
|
| + Gdiplus::Status ret = m_pGraphics->DrawRectangle(pGdiPen, rect.left, rect.top,
|
| + rect.width, rect.height);
|
| + RestoreMatrix(pMatrix);
|
| + ReleaseGdiPen(pGdiPen);
|
| + return ret == Gdiplus::Ok;
|
| +}
|
| +FX_BOOL CFDE_GdiDevice::DrawRoundRectangle(IFDE_Pen* pPen,
|
| + FX_FLOAT fPenWidth,
|
| + const CFX_RectF& rect,
|
| + const CFX_SizeF& round,
|
| + const CFX_Matrix* pMatrix) {
|
| + CFDE_GdiPath path;
|
| + path.AddRoundRectangle(rect, round);
|
| + return DrawPath(pPen, fPenWidth, &path, pMatrix);
|
| +}
|
| +FX_BOOL CFDE_GdiDevice::FillClosedCurve(IFDE_Brush* pBrush,
|
| + const CFX_PointsF& points,
|
| + FX_FLOAT fTension,
|
| + const CFX_Matrix* pMatrix) {
|
| + Gdiplus::Brush* pGdiBrush = CreateGdiBrush(pBrush);
|
| + if (pGdiBrush == NULL) {
|
| + return FALSE;
|
| + }
|
| + ApplyMatrix(pMatrix);
|
| + Gdiplus::Status ret = m_pGraphics->FillClosedCurve(
|
| + pGdiBrush, (const Gdiplus::PointF*)points.GetData(), points.GetSize(),
|
| + Gdiplus::FillModeAlternate, fTension);
|
| + RestoreMatrix(pMatrix);
|
| + ReleaseGdiBrush(pGdiBrush);
|
| + return ret == Gdiplus::Ok;
|
| +}
|
| +FX_BOOL CFDE_GdiDevice::FillEllipse(IFDE_Brush* pBrush,
|
| + const CFX_RectF& rect,
|
| + const CFX_Matrix* pMatrix) {
|
| + Gdiplus::Brush* pGdiBrush = CreateGdiBrush(pBrush);
|
| + if (pGdiBrush == NULL) {
|
| + return FALSE;
|
| + }
|
| + ApplyMatrix(pMatrix);
|
| + Gdiplus::Status ret = m_pGraphics->FillEllipse(pGdiBrush, rect.left, rect.top,
|
| + rect.width, rect.height);
|
| + RestoreMatrix(pMatrix);
|
| + ReleaseGdiBrush(pGdiBrush);
|
| + return ret == Gdiplus::Ok;
|
| +}
|
| +FX_BOOL CFDE_GdiDevice::FillPath(IFDE_Brush* pBrush,
|
| + const IFDE_Path* pPath,
|
| + const CFX_Matrix* pMatrix) {
|
| + CFDE_GdiPath* pGdiPath = (CFDE_GdiPath*)pPath;
|
| + if (pGdiPath == NULL) {
|
| + return FALSE;
|
| + }
|
| + Gdiplus::Brush* pGdiBrush = CreateGdiBrush(pBrush);
|
| + if (pGdiBrush == NULL) {
|
| + return FALSE;
|
| + }
|
| + ApplyMatrix(pMatrix);
|
| + Gdiplus::Status ret = m_pGraphics->FillPath(pGdiBrush, &pGdiPath->m_Path);
|
| + RestoreMatrix(pMatrix);
|
| + ReleaseGdiBrush(pGdiBrush);
|
| + return ret == Gdiplus::Ok;
|
| +}
|
| +FX_BOOL CFDE_GdiDevice::FillPie(IFDE_Brush* pBrush,
|
| + const CFX_RectF& rect,
|
| + FX_FLOAT startAngle,
|
| + FX_FLOAT sweepAngle,
|
| + const CFX_Matrix* pMatrix) {
|
| + startAngle = FX_RAD2DEG(startAngle);
|
| + sweepAngle = FX_RAD2DEG(sweepAngle);
|
| + Gdiplus::Brush* pGdiBrush = CreateGdiBrush(pBrush);
|
| + if (pGdiBrush == NULL) {
|
| + return FALSE;
|
| + }
|
| + ApplyMatrix(pMatrix);
|
| + Gdiplus::Status ret =
|
| + m_pGraphics->FillPie(pGdiBrush, rect.left, rect.top, rect.width,
|
| + rect.height, startAngle, sweepAngle);
|
| + RestoreMatrix(pMatrix);
|
| + ReleaseGdiBrush(pGdiBrush);
|
| + return ret == Gdiplus::Ok;
|
| +}
|
| +FX_BOOL CFDE_GdiDevice::FillChord(IFDE_Brush* pBrush,
|
| + const CFX_RectF& rect,
|
| + FX_FLOAT startAngle,
|
| + FX_FLOAT sweepAngle,
|
| + const CFX_Matrix* pMatrix) {
|
| + CFX_ArcF chord;
|
| + chord.Set(rect, startAngle, sweepAngle);
|
| + CFDE_GdiPath path;
|
| + path.AddChord(chord);
|
| + return FillPath(pBrush, &path, pMatrix);
|
| +}
|
| +FX_BOOL CFDE_GdiDevice::FillPolygon(IFDE_Brush* pBrush,
|
| + const CFX_PointsF& points,
|
| + const CFX_Matrix* pMatrix) {
|
| + Gdiplus::Brush* pGdiBrush = CreateGdiBrush(pBrush);
|
| + if (pGdiBrush == NULL) {
|
| + return FALSE;
|
| + }
|
| + ApplyMatrix(pMatrix);
|
| + Gdiplus::Status ret = m_pGraphics->FillPolygon(
|
| + pGdiBrush, (const Gdiplus::PointF*)points.GetData(), points.GetSize());
|
| + RestoreMatrix(pMatrix);
|
| + ReleaseGdiBrush(pGdiBrush);
|
| + return ret == Gdiplus::Ok;
|
| +}
|
| +FX_BOOL CFDE_GdiDevice::FillRectangle(IFDE_Brush* pBrush,
|
| + const CFX_RectF& rect,
|
| + const CFX_Matrix* pMatrix) {
|
| + Gdiplus::Brush* pGdiBrush = CreateGdiBrush(pBrush);
|
| + if (pGdiBrush == NULL) {
|
| + return FALSE;
|
| + }
|
| + ApplyMatrix(pMatrix);
|
| + Gdiplus::Status ret = m_pGraphics->FillRectangle(
|
| + pGdiBrush, rect.left, rect.top, rect.width, rect.height);
|
| + RestoreMatrix(pMatrix);
|
| + ReleaseGdiBrush(pGdiBrush);
|
| + return ret == Gdiplus::Ok;
|
| +}
|
| +FX_BOOL CFDE_GdiDevice::FillRoundRectangle(IFDE_Brush* pBrush,
|
| + const CFX_RectF& rect,
|
| + const CFX_SizeF& round,
|
| + const CFX_Matrix* pMatrix) {
|
| + CFDE_GdiPath path;
|
| + path.AddRoundRectangle(rect, round);
|
| + return FillPath(pBrush, &path, pMatrix);
|
| +}
|
| +Gdiplus::Pen* CFDE_GdiDevice::CreateGdiPen(IFDE_Pen* pPen, FX_FLOAT fPenWidth) {
|
| + if (pPen == NULL || fPenWidth < 0.01f) {
|
| + return NULL;
|
| + }
|
| + Gdiplus::Pen* pGdiPen = NULL;
|
| + switch (pPen->GetType()) {
|
| + case FDE_PENTYPE_SolidColor: {
|
| + Gdiplus::Color gdiColor((Gdiplus::ARGB)pPen->GetColor());
|
| + pGdiPen = new Gdiplus::Pen(gdiColor, fPenWidth);
|
| + } break;
|
| + case FDE_PENTYPE_HatchBrush:
|
| + case FDE_PENTYPE_TextureBrush:
|
| + case FDE_PENTYPE_LinearGradient: {
|
| + Gdiplus::Brush* pGdiBrush = CreateGdiBrush(pPen->GetBrush());
|
| + if (pGdiBrush) {
|
| + pGdiPen = new Gdiplus::Pen(pGdiBrush, fPenWidth);
|
| + }
|
| + } break;
|
| + }
|
| + if (pGdiPen) {
|
| + CFX_FloatArray dashArray;
|
| + pPen->GetDashArray(dashArray);
|
| + pGdiPen->SetDashPattern(dashArray.GetData(), dashArray.GetSize());
|
| + pGdiPen->SetDashOffset(pPen->GetDashPhase());
|
| + pGdiPen->SetDashStyle((Gdiplus::DashStyle)pPen->GetDashStyle());
|
| + pGdiPen->SetStartCap((Gdiplus::LineCap)pPen->GetLineCap());
|
| + pGdiPen->SetEndCap((Gdiplus::LineCap)pPen->GetLineCap());
|
| + pGdiPen->SetLineJoin((Gdiplus::LineJoin)pPen->GetLineJoin());
|
| + pGdiPen->SetMiterLimit(pPen->GetMiterLimit());
|
| + }
|
| + return pGdiPen;
|
| +}
|
| +void CFDE_GdiDevice::ReleaseGdiPen(Gdiplus::Pen* pGdiPen) {
|
| + if (pGdiPen) {
|
| + ReleaseGdiBrush(pGdiPen->GetBrush());
|
| + delete pGdiPen;
|
| + }
|
| +}
|
| +Gdiplus::Brush* CFDE_GdiDevice::CreateGdiBrush(IFDE_Brush* pBrush) {
|
| + if (pBrush == NULL) {
|
| + return NULL;
|
| + }
|
| + Gdiplus::Brush* pGdiBrush = NULL;
|
| + switch (pBrush->GetType()) {
|
| + case FDE_BRUSHTYPE_Solid: {
|
| + IFDE_SolidBrush* pSolidBrush = (IFDE_SolidBrush*)pBrush;
|
| + Gdiplus::Color gdiColor((Gdiplus::ARGB)pSolidBrush->GetColor());
|
| + pGdiBrush = new Gdiplus::SolidBrush(gdiColor);
|
| + } break;
|
| + case FDE_BRUSHTYPE_Hatch: {
|
| + IFDE_HatchBrush* pHatchBrush = (IFDE_HatchBrush*)pBrush;
|
| + Gdiplus::Color foreColor((Gdiplus::ARGB)pHatchBrush->GetColor(TRUE));
|
| + Gdiplus::Color backColor((Gdiplus::ARGB)pHatchBrush->GetColor(FALSE));
|
| + Gdiplus::HatchStyle hatchStyle =
|
| + (Gdiplus::HatchStyle)pHatchBrush->GetHatchStyle();
|
| + pGdiBrush = new Gdiplus::HatchBrush(hatchStyle, foreColor, backColor);
|
| + } break;
|
| + case FDE_BRUSHTYPE_Texture: {
|
| + IFDE_TextureBrush* pTextureBrush = (IFDE_TextureBrush*)pBrush;
|
| + CFDE_GdiImage* pImgHolder = (CFDE_GdiImage*)pTextureBrush->GetImage();
|
| + Gdiplus::Image* pGdiImage = pImgHolder ? pImgHolder->m_pImage : NULL;
|
| + Gdiplus::WrapMode wrapMode =
|
| + (Gdiplus::WrapMode)pTextureBrush->GetWrapMode();
|
| + pGdiBrush = new Gdiplus::TextureBrush(pGdiImage, wrapMode);
|
| + } break;
|
| + case FDE_BRUSHTYPE_LinearGradient: {
|
| + IFDE_LinearGradientBrush* pLinearBrush =
|
| + (IFDE_LinearGradientBrush*)pBrush;
|
| + Gdiplus::WrapMode wrapMode =
|
| + (Gdiplus::WrapMode)pLinearBrush->GetWrapMode();
|
| + CFX_PointF ptStart, ptEnd;
|
| + pLinearBrush->GetLinearPoints(ptStart, ptEnd);
|
| + FX_ARGB crStart, crEnd;
|
| + pLinearBrush->GetLinearColors(crStart, crEnd);
|
| + pGdiBrush = new Gdiplus::LinearGradientBrush(
|
| + (const Gdiplus::PointF&)ptStart, (const Gdiplus::PointF&)ptEnd,
|
| + (const Gdiplus::Color&)crStart, (const Gdiplus::Color&)crEnd);
|
| + } break;
|
| + }
|
| + return pGdiBrush;
|
| +}
|
| +void CFDE_GdiDevice::ReleaseGdiBrush(Gdiplus::Brush* pGdiBrush) {
|
| + if (pGdiBrush) {
|
| + delete pGdiBrush;
|
| + }
|
| +}
|
| +void CFDE_GdiDevice::ApplyMatrix(const CFX_Matrix* pMatrix) {
|
| + if (pMatrix) {
|
| + m_GraphicsState = m_pGraphics->Save();
|
| + Gdiplus::Matrix gdiMatrix(pMatrix->a, pMatrix->b, pMatrix->c, pMatrix->d,
|
| + pMatrix->e, pMatrix->f);
|
| + m_pGraphics->SetTransform(&gdiMatrix);
|
| + }
|
| +}
|
| +void CFDE_GdiDevice::RestoreMatrix(const CFX_Matrix* pMatrix) {
|
| + if (pMatrix) {
|
| + m_pGraphics->Restore(m_GraphicsState);
|
| + }
|
| +}
|
| +#endif
|
| +#endif
|
|
|