diff options
Diffstat (limited to 'core/src/fxge/win32/fx_win32_gdipext.cpp')
-rw-r--r-- | core/src/fxge/win32/fx_win32_gdipext.cpp | 1518 |
1 files changed, 0 insertions, 1518 deletions
diff --git a/core/src/fxge/win32/fx_win32_gdipext.cpp b/core/src/fxge/win32/fx_win32_gdipext.cpp deleted file mode 100644 index aba67dacfe..0000000000 --- a/core/src/fxge/win32/fx_win32_gdipext.cpp +++ /dev/null @@ -1,1518 +0,0 @@ -// 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 "core/include/fxge/fx_ge.h" - -#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_DESKTOP_ -#include <windows.h> -#include <algorithm> - -namespace Gdiplus { -using std::min; -using std::max; -} // namespace Gdiplus - -#include <gdiplus.h> - -#include "core/include/fxge/fx_ge_win32.h" -#include "core/src/fxge/win32/win32_int.h" - -using namespace Gdiplus; // NOLINT -using namespace Gdiplus::DllExports; // NOLINT - -#define GdiFillType2Gdip(fill_type) \ - (fill_type == ALTERNATE ? FillModeAlternate : FillModeWinding) - -enum { - FuncId_GdipCreatePath2, - FuncId_GdipSetPenDashStyle, - FuncId_GdipSetPenDashArray, - FuncId_GdipSetPenDashCap197819, - FuncId_GdipSetPenLineJoin, - FuncId_GdipSetPenWidth, - FuncId_GdipCreateFromHDC, - FuncId_GdipSetPageUnit, - FuncId_GdipSetSmoothingMode, - FuncId_GdipCreateSolidFill, - FuncId_GdipFillPath, - FuncId_GdipDeleteBrush, - FuncId_GdipCreatePen1, - FuncId_GdipSetPenMiterLimit, - FuncId_GdipDrawPath, - FuncId_GdipDeletePen, - FuncId_GdipDeletePath, - FuncId_GdipDeleteGraphics, - FuncId_GdipCreateBitmapFromFileICM, - FuncId_GdipCreateBitmapFromStreamICM, - FuncId_GdipGetImageHeight, - FuncId_GdipGetImageWidth, - FuncId_GdipGetImagePixelFormat, - FuncId_GdipBitmapLockBits, - FuncId_GdipGetImagePaletteSize, - FuncId_GdipGetImagePalette, - FuncId_GdipBitmapUnlockBits, - FuncId_GdipDisposeImage, - FuncId_GdipFillRectangle, - FuncId_GdipCreateBitmapFromScan0, - FuncId_GdipSetImagePalette, - FuncId_GdipSetInterpolationMode, - FuncId_GdipDrawImagePointsI, - FuncId_GdipCreateBitmapFromGdiDib, - FuncId_GdiplusStartup, - FuncId_GdipDrawLineI, - FuncId_GdipResetClip, - FuncId_GdipCreatePath, - FuncId_GdipAddPathPath, - FuncId_GdipSetPathFillMode, - FuncId_GdipSetClipPath, - FuncId_GdipGetClip, - FuncId_GdipCreateRegion, - FuncId_GdipGetClipBoundsI, - FuncId_GdipSetClipRegion, - FuncId_GdipWidenPath, - FuncId_GdipAddPathLine, - FuncId_GdipAddPathRectangle, - FuncId_GdipDeleteRegion, - FuncId_GdipGetDC, - FuncId_GdipReleaseDC, - FuncId_GdipSetPenLineCap197819, - FuncId_GdipSetPenDashOffset, - FuncId_GdipResetPath, - FuncId_GdipCreateRegionPath, - FuncId_GdipCreateFont, - FuncId_GdipGetFontSize, - FuncId_GdipCreateFontFamilyFromName, - FuncId_GdipSetTextRenderingHint, - FuncId_GdipDrawDriverString, - FuncId_GdipCreateMatrix2, - FuncId_GdipDeleteMatrix, - FuncId_GdipSetWorldTransform, - FuncId_GdipResetWorldTransform, - FuncId_GdipDeleteFontFamily, - FuncId_GdipDeleteFont, - FuncId_GdipNewPrivateFontCollection, - FuncId_GdipDeletePrivateFontCollection, - FuncId_GdipPrivateAddMemoryFont, - FuncId_GdipGetFontCollectionFamilyList, - FuncId_GdipGetFontCollectionFamilyCount, - FuncId_GdipSetTextContrast, - FuncId_GdipSetPixelOffsetMode, - FuncId_GdipGetImageGraphicsContext, - FuncId_GdipDrawImageI, - FuncId_GdipDrawImageRectI, - FuncId_GdipDrawString, - FuncId_GdipSetPenTransform, -}; -static LPCSTR g_GdipFuncNames[] = { - "GdipCreatePath2", - "GdipSetPenDashStyle", - "GdipSetPenDashArray", - "GdipSetPenDashCap197819", - "GdipSetPenLineJoin", - "GdipSetPenWidth", - "GdipCreateFromHDC", - "GdipSetPageUnit", - "GdipSetSmoothingMode", - "GdipCreateSolidFill", - "GdipFillPath", - "GdipDeleteBrush", - "GdipCreatePen1", - "GdipSetPenMiterLimit", - "GdipDrawPath", - "GdipDeletePen", - "GdipDeletePath", - "GdipDeleteGraphics", - "GdipCreateBitmapFromFileICM", - "GdipCreateBitmapFromStreamICM", - "GdipGetImageHeight", - "GdipGetImageWidth", - "GdipGetImagePixelFormat", - "GdipBitmapLockBits", - "GdipGetImagePaletteSize", - "GdipGetImagePalette", - "GdipBitmapUnlockBits", - "GdipDisposeImage", - "GdipFillRectangle", - "GdipCreateBitmapFromScan0", - "GdipSetImagePalette", - "GdipSetInterpolationMode", - "GdipDrawImagePointsI", - "GdipCreateBitmapFromGdiDib", - "GdiplusStartup", - "GdipDrawLineI", - "GdipResetClip", - "GdipCreatePath", - "GdipAddPathPath", - "GdipSetPathFillMode", - "GdipSetClipPath", - "GdipGetClip", - "GdipCreateRegion", - "GdipGetClipBoundsI", - "GdipSetClipRegion", - "GdipWidenPath", - "GdipAddPathLine", - "GdipAddPathRectangle", - "GdipDeleteRegion", - "GdipGetDC", - "GdipReleaseDC", - "GdipSetPenLineCap197819", - "GdipSetPenDashOffset", - "GdipResetPath", - "GdipCreateRegionPath", - "GdipCreateFont", - "GdipGetFontSize", - "GdipCreateFontFamilyFromName", - "GdipSetTextRenderingHint", - "GdipDrawDriverString", - "GdipCreateMatrix2", - "GdipDeleteMatrix", - "GdipSetWorldTransform", - "GdipResetWorldTransform", - "GdipDeleteFontFamily", - "GdipDeleteFont", - "GdipNewPrivateFontCollection", - "GdipDeletePrivateFontCollection", - "GdipPrivateAddMemoryFont", - "GdipGetFontCollectionFamilyList", - "GdipGetFontCollectionFamilyCount", - "GdipSetTextContrast", - "GdipSetPixelOffsetMode", - "GdipGetImageGraphicsContext", - "GdipDrawImageI", - "GdipDrawImageRectI", - "GdipDrawString", - "GdipSetPenTransform", -}; -typedef GpStatus(WINGDIPAPI* FuncType_GdipCreatePath2)(GDIPCONST GpPointF*, - GDIPCONST BYTE*, - INT, - GpFillMode, - GpPath** path); -typedef GpStatus(WINGDIPAPI* FuncType_GdipSetPenDashStyle)( - GpPen* pen, - GpDashStyle dashstyle); -typedef GpStatus(WINGDIPAPI* FuncType_GdipSetPenDashArray)(GpPen* pen, - GDIPCONST REAL* dash, - INT count); -typedef GpStatus(WINGDIPAPI* FuncType_GdipSetPenDashCap197819)( - GpPen* pen, - GpDashCap dashCap); -typedef GpStatus(WINGDIPAPI* FuncType_GdipSetPenLineJoin)(GpPen* pen, - GpLineJoin lineJoin); -typedef GpStatus(WINGDIPAPI* FuncType_GdipSetPenWidth)(GpPen* pen, REAL width); -typedef GpStatus(WINGDIPAPI* FuncType_GdipCreateFromHDC)(HDC hdc, - GpGraphics** graphics); -typedef GpStatus(WINGDIPAPI* FuncType_GdipSetPageUnit)(GpGraphics* graphics, - GpUnit unit); -typedef GpStatus(WINGDIPAPI* FuncType_GdipSetSmoothingMode)( - GpGraphics* graphics, - SmoothingMode smoothingMode); -typedef GpStatus(WINGDIPAPI* FuncType_GdipCreateSolidFill)(ARGB color, - GpSolidFill** brush); -typedef GpStatus(WINGDIPAPI* FuncType_GdipFillPath)(GpGraphics* graphics, - GpBrush* brush, - GpPath* path); -typedef GpStatus(WINGDIPAPI* FuncType_GdipDeleteBrush)(GpBrush* brush); -typedef GpStatus(WINGDIPAPI* FuncType_GdipCreatePen1)(ARGB color, - REAL width, - GpUnit unit, - GpPen** pen); -typedef GpStatus(WINGDIPAPI* FuncType_GdipSetPenMiterLimit)(GpPen* pen, - REAL miterLimit); -typedef GpStatus(WINGDIPAPI* FuncType_GdipDrawPath)(GpGraphics* graphics, - GpPen* pen, - GpPath* path); -typedef GpStatus(WINGDIPAPI* FuncType_GdipDeletePen)(GpPen* pen); -typedef GpStatus(WINGDIPAPI* FuncType_GdipDeletePath)(GpPath* path); -typedef GpStatus(WINGDIPAPI* FuncType_GdipDeleteGraphics)(GpGraphics* graphics); -typedef GpStatus(WINGDIPAPI* FuncType_GdipCreateBitmapFromFileICM)( - GDIPCONST WCHAR* filename, - GpBitmap** bitmap); -typedef GpStatus(WINGDIPAPI* FuncType_GdipCreateBitmapFromStreamICM)( - IStream* stream, - GpBitmap** bitmap); -typedef GpStatus(WINGDIPAPI* FuncType_GdipGetImageWidth)(GpImage* image, - UINT* width); -typedef GpStatus(WINGDIPAPI* FuncType_GdipGetImageHeight)(GpImage* image, - UINT* height); -typedef GpStatus(WINGDIPAPI* FuncType_GdipGetImagePixelFormat)( - GpImage* image, - PixelFormat* format); -typedef GpStatus(WINGDIPAPI* FuncType_GdipBitmapLockBits)( - GpBitmap* bitmap, - GDIPCONST GpRect* rect, - UINT flags, - PixelFormat format, - BitmapData* lockedBitmapData); -typedef GpStatus(WINGDIPAPI* FuncType_GdipGetImagePalette)( - GpImage* image, - ColorPalette* palette, - INT size); -typedef GpStatus(WINGDIPAPI* FuncType_GdipGetImagePaletteSize)(GpImage* image, - INT* size); -typedef GpStatus(WINGDIPAPI* FuncType_GdipBitmapUnlockBits)( - GpBitmap* bitmap, - BitmapData* lockedBitmapData); -typedef GpStatus(WINGDIPAPI* FuncType_GdipDisposeImage)(GpImage* image); -typedef GpStatus(WINGDIPAPI* FuncType_GdipFillRectangle)(GpGraphics* graphics, - GpBrush* brush, - REAL x, - REAL y, - REAL width, - REAL height); -typedef GpStatus(WINGDIPAPI* FuncType_GdipCreateBitmapFromScan0)( - INT width, - INT height, - INT stride, - PixelFormat format, - BYTE* scan0, - GpBitmap** bitmap); -typedef GpStatus(WINGDIPAPI* FuncType_GdipSetImagePalette)( - GpImage* image, - GDIPCONST ColorPalette* palette); -typedef GpStatus(WINGDIPAPI* FuncType_GdipSetInterpolationMode)( - GpGraphics* graphics, - InterpolationMode interpolationMode); -typedef GpStatus(WINGDIPAPI* FuncType_GdipDrawImagePointsI)( - GpGraphics* graphics, - GpImage* image, - GDIPCONST GpPoint* dstpoints, - INT count); -typedef GpStatus(WINGDIPAPI* FuncType_GdipCreateBitmapFromGdiDib)( - GDIPCONST BITMAPINFO* gdiBitmapInfo, - VOID* gdiBitmapData, - GpBitmap** bitmap); -typedef Status(WINAPI* FuncType_GdiplusStartup)( - OUT uintptr_t* token, - const GdiplusStartupInput* input, - OUT GdiplusStartupOutput* output); -typedef GpStatus(WINGDIPAPI* FuncType_GdipDrawLineI)(GpGraphics* graphics, - GpPen* pen, - int x1, - int y1, - int x2, - int y2); -typedef GpStatus(WINGDIPAPI* FuncType_GdipResetClip)(GpGraphics* graphics); -typedef GpStatus(WINGDIPAPI* FuncType_GdipCreatePath)(GpFillMode brushMode, - GpPath** path); -typedef GpStatus(WINGDIPAPI* FuncType_GdipAddPathPath)( - GpPath* path, - GDIPCONST GpPath* addingPath, - BOOL connect); -typedef GpStatus(WINGDIPAPI* FuncType_GdipSetPathFillMode)(GpPath* path, - GpFillMode fillmode); -typedef GpStatus(WINGDIPAPI* FuncType_GdipSetClipPath)(GpGraphics* graphics, - GpPath* path, - CombineMode combineMode); -typedef GpStatus(WINGDIPAPI* FuncType_GdipGetClip)(GpGraphics* graphics, - GpRegion* region); -typedef GpStatus(WINGDIPAPI* FuncType_GdipCreateRegion)(GpRegion** region); -typedef GpStatus(WINGDIPAPI* FuncType_GdipGetClipBoundsI)(GpGraphics* graphics, - GpRect* rect); -typedef GpStatus(WINGDIPAPI* FuncType_GdipSetClipRegion)( - GpGraphics* graphics, - GpRegion* region, - CombineMode combineMode); -typedef GpStatus(WINGDIPAPI* FuncType_GdipWidenPath)(GpPath* nativePath, - GpPen* pen, - GpMatrix* matrix, - REAL flatness); -typedef GpStatus(WINGDIPAPI* FuncType_GdipAddPathLine)(GpPath* path, - REAL x1, - REAL y1, - REAL x2, - REAL y2); -typedef GpStatus(WINGDIPAPI* FuncType_GdipAddPathRectangle)(GpPath* path, - REAL x, - REAL y, - REAL width, - REAL height); -typedef GpStatus(WINGDIPAPI* FuncType_GdipDeleteRegion)(GpRegion* region); -typedef GpStatus(WINGDIPAPI* FuncType_GdipGetDC)(GpGraphics* graphics, - HDC* hdc); -typedef GpStatus(WINGDIPAPI* FuncType_GdipReleaseDC)(GpGraphics* graphics, - HDC hdc); -typedef GpStatus(WINGDIPAPI* FuncType_GdipSetPenLineCap197819)( - GpPen* pen, - GpLineCap startCap, - GpLineCap endCap, - GpDashCap dashCap); -typedef GpStatus(WINGDIPAPI* FuncType_GdipSetPenDashOffset)(GpPen* pen, - REAL offset); -typedef GpStatus(WINGDIPAPI* FuncType_GdipResetPath)(GpPath* path); -typedef GpStatus(WINGDIPAPI* FuncType_GdipCreateRegionPath)(GpPath* path, - GpRegion** region); -typedef GpStatus(WINGDIPAPI* FuncType_GdipCreateFont)( - GDIPCONST GpFontFamily* fontFamily, - REAL emSize, - INT style, - Unit unit, - GpFont** font); -typedef GpStatus(WINGDIPAPI* FuncType_GdipGetFontSize)(GpFont* font, - REAL* size); -typedef GpStatus(WINGDIPAPI* FuncType_GdipCreateFontFamilyFromName)( - GDIPCONST WCHAR* name, - GpFontCollection* fontCollection, - GpFontFamily** FontFamily); -typedef GpStatus(WINGDIPAPI* FuncType_GdipSetTextRenderingHint)( - GpGraphics* graphics, - TextRenderingHint mode); -typedef GpStatus(WINGDIPAPI* FuncType_GdipDrawDriverString)( - GpGraphics* graphics, - GDIPCONST UINT16* text, - INT length, - GDIPCONST GpFont* font, - GDIPCONST GpBrush* brush, - GDIPCONST PointF* positions, - INT flags, - GDIPCONST GpMatrix* matrix); -typedef GpStatus(WINGDIPAPI* FuncType_GdipCreateMatrix2)(REAL m11, - REAL m12, - REAL m21, - REAL m22, - REAL dx, - REAL dy, - GpMatrix** matrix); -typedef GpStatus(WINGDIPAPI* FuncType_GdipDeleteMatrix)(GpMatrix* matrix); -typedef GpStatus(WINGDIPAPI* FuncType_GdipSetWorldTransform)( - GpGraphics* graphics, - GpMatrix* matrix); -typedef GpStatus(WINGDIPAPI* FuncType_GdipResetWorldTransform)( - GpGraphics* graphics); -typedef GpStatus(WINGDIPAPI* FuncType_GdipDeleteFontFamily)( - GpFontFamily* FontFamily); -typedef GpStatus(WINGDIPAPI* FuncType_GdipDeleteFont)(GpFont* font); -typedef GpStatus(WINGDIPAPI* FuncType_GdipNewPrivateFontCollection)( - GpFontCollection** fontCollection); -typedef GpStatus(WINGDIPAPI* FuncType_GdipDeletePrivateFontCollection)( - GpFontCollection** fontCollection); -typedef GpStatus(WINGDIPAPI* FuncType_GdipPrivateAddMemoryFont)( - GpFontCollection* fontCollection, - GDIPCONST void* memory, - INT length); -typedef GpStatus(WINGDIPAPI* FuncType_GdipGetFontCollectionFamilyList)( - GpFontCollection* fontCollection, - INT numSought, - GpFontFamily* gpfamilies[], - INT* numFound); -typedef GpStatus(WINGDIPAPI* FuncType_GdipGetFontCollectionFamilyCount)( - GpFontCollection* fontCollection, - INT* numFound); -typedef GpStatus(WINGDIPAPI* FuncType_GdipSetTextContrast)(GpGraphics* graphics, - UINT contrast); -typedef GpStatus(WINGDIPAPI* FuncType_GdipSetPixelOffsetMode)( - GpGraphics* graphics, - PixelOffsetMode pixelOffsetMode); -typedef GpStatus(WINGDIPAPI* FuncType_GdipGetImageGraphicsContext)( - GpImage* image, - GpGraphics** graphics); -typedef GpStatus(WINGDIPAPI* FuncType_GdipDrawImageI)(GpGraphics* graphics, - GpImage* image, - INT x, - INT y); -typedef GpStatus(WINGDIPAPI* FuncType_GdipDrawImageRectI)(GpGraphics* graphics, - GpImage* image, - INT x, - INT y, - INT width, - INT height); -typedef GpStatus(WINGDIPAPI* FuncType_GdipDrawString)( - GpGraphics* graphics, - GDIPCONST WCHAR* str, - INT length, - GDIPCONST GpFont* font, - GDIPCONST RectF* layoutRect, - GDIPCONST GpStringFormat* stringFormat, - GDIPCONST GpBrush* brush); -typedef GpStatus(WINGDIPAPI* FuncType_GdipSetPenTransform)(GpPen* pen, - GpMatrix* matrix); -#define CallFunc(funcname) \ - ((FuncType_##funcname)GdiplusExt.m_Functions[FuncId_##funcname]) -typedef HANDLE(__stdcall* FuncType_GdiAddFontMemResourceEx)(PVOID pbFont, - DWORD cbFont, - PVOID pdv, - DWORD* pcFonts); -typedef BOOL(__stdcall* FuncType_GdiRemoveFontMemResourceEx)(HANDLE handle); -void* CGdiplusExt::GdiAddFontMemResourceEx(void* pFontdata, - FX_DWORD size, - void* pdv, - FX_DWORD* num_face) { - if (m_pGdiAddFontMemResourceEx) { - return ((FuncType_GdiAddFontMemResourceEx)m_pGdiAddFontMemResourceEx)( - (PVOID)pFontdata, (DWORD)size, (PVOID)pdv, (DWORD*)num_face); - } - return NULL; -} -FX_BOOL CGdiplusExt::GdiRemoveFontMemResourceEx(void* handle) { - if (m_pGdiRemoveFontMemResourseEx) { - return ((FuncType_GdiRemoveFontMemResourceEx)m_pGdiRemoveFontMemResourseEx)( - (HANDLE)handle); - } - return FALSE; -} -static GpBrush* _GdipCreateBrush(DWORD argb) { - CGdiplusExt& GdiplusExt = - ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - GpSolidFill* solidBrush = NULL; - CallFunc(GdipCreateSolidFill)((ARGB)argb, &solidBrush); - return solidBrush; -} -static CFX_DIBitmap* _StretchMonoToGray(int dest_width, - int dest_height, - const CFX_DIBitmap* pSource, - FX_RECT* pClipRect) { - FX_BOOL bFlipX = dest_width < 0; - if (bFlipX) { - dest_width = -dest_width; - } - FX_BOOL bFlipY = dest_height < 0; - if (bFlipY) { - dest_height = -dest_height; - } - int result_width = pClipRect->Width(); - int result_height = pClipRect->Height(); - int result_pitch = (result_width + 3) / 4 * 4; - CFX_DIBitmap* pStretched = new CFX_DIBitmap; - if (!pStretched->Create(result_width, result_height, FXDIB_8bppRgb)) { - delete pStretched; - return NULL; - } - LPBYTE dest_buf = pStretched->GetBuffer(); - int src_width = pSource->GetWidth(); - int src_height = pSource->GetHeight(); - int y_unit = src_height / dest_height; - int x_unit = src_width / dest_width; - int area_unit = y_unit * x_unit; - LPBYTE src_buf = pSource->GetBuffer(); - int src_pitch = pSource->GetPitch(); - for (int dest_y = 0; dest_y < result_height; dest_y++) { - LPBYTE dest_scan = dest_buf + dest_y * result_pitch; - int src_y_start = bFlipY ? (dest_height - 1 - dest_y - pClipRect->top) - : (dest_y + pClipRect->top); - src_y_start = src_y_start * src_height / dest_height; - LPBYTE src_scan = src_buf + src_y_start * src_pitch; - for (int dest_x = 0; dest_x < result_width; dest_x++) { - int sum = 0; - int src_x_start = bFlipX ? (dest_width - 1 - dest_x - pClipRect->left) - : (dest_x + pClipRect->left); - src_x_start = src_x_start * src_width / dest_width; - int src_x_end = src_x_start + x_unit; - LPBYTE src_line = src_scan; - for (int src_y = 0; src_y < y_unit; src_y++) { - for (int src_x = src_x_start; src_x < src_x_end; src_x++) { - if (!(src_line[src_x / 8] & (1 << (7 - src_x % 8)))) { - sum += 255; - } - } - src_line += src_pitch; - } - dest_scan[dest_x] = 255 - sum / area_unit; - } - } - return pStretched; -} -static void OutputImageMask(GpGraphics* pGraphics, - BOOL bMonoDevice, - const CFX_DIBitmap* pBitmap, - int dest_left, - int dest_top, - int dest_width, - int dest_height, - FX_ARGB argb, - const FX_RECT* pClipRect) { - ASSERT(pBitmap->GetBPP() == 1); - CGdiplusExt& GdiplusExt = - ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - int src_width = pBitmap->GetWidth(), src_height = pBitmap->GetHeight(); - int src_pitch = pBitmap->GetPitch(); - uint8_t* scan0 = pBitmap->GetBuffer(); - if (src_width == 1 && src_height == 1) { - if ((scan0[0] & 0x80) == 0) { - return; - } - GpSolidFill* solidBrush; - CallFunc(GdipCreateSolidFill)((ARGB)argb, &solidBrush); - if (dest_width < 0) { - dest_width = -dest_width; - dest_left -= dest_width; - } - if (dest_height < 0) { - dest_height = -dest_height; - dest_top -= dest_height; - } - CallFunc(GdipFillRectangle)(pGraphics, solidBrush, (float)dest_left, - (float)dest_top, (float)dest_width, - (float)dest_height); - CallFunc(GdipDeleteBrush)(solidBrush); - return; - } - if (!bMonoDevice && abs(dest_width) < src_width && - abs(dest_height) < src_height) { - FX_RECT image_rect(dest_left, dest_top, dest_left + dest_width, - dest_top + dest_height); - image_rect.Normalize(); - FX_RECT image_clip = image_rect; - image_clip.Intersect(*pClipRect); - if (image_clip.IsEmpty()) { - return; - } - image_clip.Offset(-image_rect.left, -image_rect.top); - CFX_DIBitmap* pStretched = NULL; - if (src_width * src_height > 10000) { - pStretched = - _StretchMonoToGray(dest_width, dest_height, pBitmap, &image_clip); - } else { - pStretched = - pBitmap->StretchTo(dest_width, dest_height, FALSE, &image_clip); - } - GpBitmap* bitmap; - CallFunc(GdipCreateBitmapFromScan0)(image_clip.Width(), image_clip.Height(), - (image_clip.Width() + 3) / 4 * 4, - PixelFormat8bppIndexed, - pStretched->GetBuffer(), &bitmap); - int a, r, g, b; - ArgbDecode(argb, a, r, g, b); - UINT pal[258]; - pal[0] = 0; - pal[1] = 256; - for (int i = 0; i < 256; i++) { - pal[i + 2] = ArgbEncode(i * a / 255, r, g, b); - } - CallFunc(GdipSetImagePalette)(bitmap, (ColorPalette*)pal); - CallFunc(GdipDrawImageI)(pGraphics, bitmap, - image_rect.left + image_clip.left, - image_rect.top + image_clip.top); - CallFunc(GdipDisposeImage)(bitmap); - delete pStretched; - return; - } - GpBitmap* bitmap; - CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch, - PixelFormat1bppIndexed, scan0, &bitmap); - UINT palette[4] = {PaletteFlagsHasAlpha, 2, 0, argb}; - CallFunc(GdipSetImagePalette)(bitmap, (ColorPalette*)palette); - Point destinationPoints[] = {Point(dest_left, dest_top), - Point(dest_left + dest_width, dest_top), - Point(dest_left, dest_top + dest_height)}; - CallFunc(GdipDrawImagePointsI)(pGraphics, bitmap, destinationPoints, 3); - CallFunc(GdipDisposeImage)(bitmap); -} -static void OutputImage(GpGraphics* pGraphics, - const CFX_DIBitmap* pBitmap, - const FX_RECT* pSrcRect, - int dest_left, - int dest_top, - int dest_width, - int dest_height) { - int src_width = pSrcRect->Width(), src_height = pSrcRect->Height(); - CGdiplusExt& GdiplusExt = - ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - if (pBitmap->GetBPP() == 1 && (pSrcRect->left % 8)) { - FX_RECT new_rect(0, 0, src_width, src_height); - CFX_DIBitmap* pCloned = pBitmap->Clone(pSrcRect); - if (!pCloned) { - return; - } - OutputImage(pGraphics, pCloned, &new_rect, dest_left, dest_top, dest_width, - dest_height); - delete pCloned; - return; - } - int src_pitch = pBitmap->GetPitch(); - uint8_t* scan0 = pBitmap->GetBuffer() + pSrcRect->top * src_pitch + - pBitmap->GetBPP() * pSrcRect->left / 8; - GpBitmap* bitmap = NULL; - switch (pBitmap->GetFormat()) { - case FXDIB_Argb: - CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch, - PixelFormat32bppARGB, scan0, &bitmap); - break; - case FXDIB_Rgb32: - CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch, - PixelFormat32bppRGB, scan0, &bitmap); - break; - case FXDIB_Rgb: - CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch, - PixelFormat24bppRGB, scan0, &bitmap); - break; - case FXDIB_8bppRgb: { - CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch, - PixelFormat8bppIndexed, scan0, - &bitmap); - UINT pal[258]; - pal[0] = 0; - pal[1] = 256; - for (int i = 0; i < 256; i++) { - pal[i + 2] = pBitmap->GetPaletteEntry(i); - } - CallFunc(GdipSetImagePalette)(bitmap, (ColorPalette*)pal); - break; - } - case FXDIB_1bppRgb: { - CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch, - PixelFormat1bppIndexed, scan0, - &bitmap); - break; - } - } - if (dest_height < 0) { - dest_height--; - } - if (dest_width < 0) { - dest_width--; - } - Point destinationPoints[] = {Point(dest_left, dest_top), - Point(dest_left + dest_width, dest_top), - Point(dest_left, dest_top + dest_height)}; - CallFunc(GdipDrawImagePointsI)(pGraphics, bitmap, destinationPoints, 3); - CallFunc(GdipDisposeImage)(bitmap); -} -CGdiplusExt::CGdiplusExt() { - m_hModule = NULL; - m_GdiModule = NULL; - for (int i = 0; i < sizeof g_GdipFuncNames / sizeof(LPCSTR); i++) { - m_Functions[i] = NULL; - } - m_pGdiAddFontMemResourceEx = NULL; - m_pGdiRemoveFontMemResourseEx = NULL; -} -void CGdiplusExt::Load() { - CFX_ByteString strPlusPath = ""; - FX_CHAR buf[MAX_PATH]; - GetSystemDirectoryA(buf, MAX_PATH); - strPlusPath += buf; - strPlusPath += "\\"; - strPlusPath += "GDIPLUS.DLL"; - m_hModule = LoadLibraryA(strPlusPath); - if (!m_hModule) { - return; - } - for (int i = 0; i < sizeof g_GdipFuncNames / sizeof(LPCSTR); i++) { - m_Functions[i] = GetProcAddress(m_hModule, g_GdipFuncNames[i]); - if (!m_Functions[i]) { - m_hModule = NULL; - return; - } - } - uintptr_t gdiplusToken; - GdiplusStartupInput gdiplusStartupInput; - ((FuncType_GdiplusStartup)m_Functions[FuncId_GdiplusStartup])( - &gdiplusToken, &gdiplusStartupInput, NULL); - m_GdiModule = LoadLibraryA("GDI32.DLL"); - if (!m_GdiModule) { - return; - } - m_pGdiAddFontMemResourceEx = - GetProcAddress(m_GdiModule, "AddFontMemResourceEx"); - m_pGdiRemoveFontMemResourseEx = - GetProcAddress(m_GdiModule, "RemoveFontMemResourceEx"); -} -CGdiplusExt::~CGdiplusExt() {} -LPVOID CGdiplusExt::LoadMemFont(LPBYTE pData, FX_DWORD size) { - GpFontCollection* pCollection = NULL; - CGdiplusExt& GdiplusExt = - ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - CallFunc(GdipNewPrivateFontCollection)(&pCollection); - GpStatus status = - CallFunc(GdipPrivateAddMemoryFont)(pCollection, pData, size); - if (status == Ok) { - return pCollection; - } - CallFunc(GdipDeletePrivateFontCollection)(&pCollection); - return NULL; -} -void CGdiplusExt::DeleteMemFont(LPVOID pCollection) { - CGdiplusExt& GdiplusExt = - ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - CallFunc(GdipDeletePrivateFontCollection)((GpFontCollection**)&pCollection); -} -FX_BOOL CGdiplusExt::GdipCreateBitmap(CFX_DIBitmap* pBitmap, void** bitmap) { - CGdiplusExt& GdiplusExt = - ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - PixelFormat format; - switch (pBitmap->GetFormat()) { - case FXDIB_Rgb: - format = PixelFormat24bppRGB; - break; - case FXDIB_Rgb32: - format = PixelFormat32bppRGB; - break; - case FXDIB_Argb: - format = PixelFormat32bppARGB; - break; - default: - return FALSE; - } - GpStatus status = CallFunc(GdipCreateBitmapFromScan0)( - pBitmap->GetWidth(), pBitmap->GetHeight(), pBitmap->GetPitch(), format, - pBitmap->GetBuffer(), (GpBitmap**)bitmap); - if (status == Ok) { - return TRUE; - } - return FALSE; -} -FX_BOOL CGdiplusExt::GdipCreateFromImage(void* bitmap, void** graphics) { - CGdiplusExt& GdiplusExt = - ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - GpStatus status = CallFunc(GdipGetImageGraphicsContext)( - (GpBitmap*)bitmap, (GpGraphics**)graphics); - if (status == Ok) { - return TRUE; - } - return FALSE; -} -FX_BOOL CGdiplusExt::GdipCreateFontFamilyFromName(const FX_WCHAR* name, - void* pFontCollection, - void** pFamily) { - CGdiplusExt& GdiplusExt = - ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - GpStatus status = CallFunc(GdipCreateFontFamilyFromName)( - (GDIPCONST WCHAR*)name, (GpFontCollection*)pFontCollection, - (GpFontFamily**)pFamily); - if (status == Ok) { - return TRUE; - } - return FALSE; -} -FX_BOOL CGdiplusExt::GdipCreateFontFromFamily(void* pFamily, - FX_FLOAT font_size, - int fontstyle, - int flag, - void** pFont) { - CGdiplusExt& GdiplusExt = - ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - GpStatus status = - CallFunc(GdipCreateFont)((GpFontFamily*)pFamily, font_size, fontstyle, - Unit(flag), (GpFont**)pFont); - if (status == Ok) { - return TRUE; - } - return FALSE; -} -void CGdiplusExt::GdipGetFontSize(void* pFont, FX_FLOAT* size) { - REAL get_size; - CGdiplusExt& GdiplusExt = - ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - GpStatus status = CallFunc(GdipGetFontSize)((GpFont*)pFont, (REAL*)&get_size); - if (status == Ok) { - *size = (FX_FLOAT)get_size; - } else { - *size = 0; - } -} -void CGdiplusExt::GdipSetTextRenderingHint(void* graphics, int mode) { - CGdiplusExt& GdiplusExt = - ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - CallFunc(GdipSetTextRenderingHint)((GpGraphics*)graphics, - (TextRenderingHint)mode); -} -void CGdiplusExt::GdipSetPageUnit(void* graphics, FX_DWORD unit) { - CGdiplusExt& GdiplusExt = - ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - CallFunc(GdipSetPageUnit)((GpGraphics*)graphics, (GpUnit)unit); -} -FX_BOOL CGdiplusExt::GdipDrawDriverString(void* graphics, - unsigned short* text, - int length, - void* font, - void* brush, - void* positions, - int flags, - const void* matrix) { - CGdiplusExt& GdiplusExt = - ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - GpStatus status = CallFunc(GdipDrawDriverString)( - (GpGraphics*)graphics, (GDIPCONST UINT16*)text, (INT)length, - (GDIPCONST GpFont*)font, (GDIPCONST GpBrush*)brush, - (GDIPCONST PointF*)positions, (INT)flags, (GDIPCONST GpMatrix*)matrix); - if (status == Ok) { - return TRUE; - } - return FALSE; -} -void CGdiplusExt::GdipCreateBrush(FX_DWORD fill_argb, void** pBrush) { - CGdiplusExt& GdiplusExt = - ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - CallFunc(GdipCreateSolidFill)((ARGB)fill_argb, (GpSolidFill**)pBrush); -} -void CGdiplusExt::GdipDeleteBrush(void* pBrush) { - CGdiplusExt& GdiplusExt = - ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - CallFunc(GdipDeleteBrush)((GpSolidFill*)pBrush); -} -void* CGdiplusExt::GdipCreateFontFromCollection(void* pFontCollection, - FX_FLOAT font_size, - int fontstyle) { - CGdiplusExt& GdiplusExt = - ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - int numFamilies = 0; - GpStatus status = CallFunc(GdipGetFontCollectionFamilyCount)( - (GpFontCollection*)pFontCollection, &numFamilies); - if (status != Ok) { - return NULL; - } - GpFontFamily* family_list[1]; - status = CallFunc(GdipGetFontCollectionFamilyList)( - (GpFontCollection*)pFontCollection, 1, family_list, &numFamilies); - if (status != Ok) { - return NULL; - } - GpFont* pFont = NULL; - status = CallFunc(GdipCreateFont)(family_list[0], font_size, fontstyle, - UnitPixel, &pFont); - if (status != Ok) { - return NULL; - } - return pFont; -} -void CGdiplusExt::GdipCreateMatrix(FX_FLOAT a, - FX_FLOAT b, - FX_FLOAT c, - FX_FLOAT d, - FX_FLOAT e, - FX_FLOAT f, - void** matrix) { - CGdiplusExt& GdiplusExt = - ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - CallFunc(GdipCreateMatrix2)(a, b, c, d, e, f, (GpMatrix**)matrix); -} -void CGdiplusExt::GdipDeleteMatrix(void* matrix) { - CGdiplusExt& GdiplusExt = - ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - CallFunc(GdipDeleteMatrix)((GpMatrix*)matrix); -} -void CGdiplusExt::GdipDeleteFontFamily(void* pFamily) { - CGdiplusExt& GdiplusExt = - ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - CallFunc(GdipDeleteFontFamily)((GpFontFamily*)pFamily); -} -void CGdiplusExt::GdipDeleteFont(void* pFont) { - CGdiplusExt& GdiplusExt = - ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - CallFunc(GdipDeleteFont)((GpFont*)pFont); -} -void CGdiplusExt::GdipSetWorldTransform(void* graphics, void* pMatrix) { - CGdiplusExt& GdiplusExt = - ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - CallFunc(GdipSetWorldTransform)((GpGraphics*)graphics, (GpMatrix*)pMatrix); -} -void CGdiplusExt::GdipDisposeImage(void* bitmap) { - CGdiplusExt& GdiplusExt = - ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - CallFunc(GdipDisposeImage)((GpBitmap*)bitmap); -} -void CGdiplusExt::GdipDeleteGraphics(void* graphics) { - CGdiplusExt& GdiplusExt = - ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - CallFunc(GdipDeleteGraphics)((GpGraphics*)graphics); -} -FX_BOOL CGdiplusExt::StretchBitMask(HDC hDC, - BOOL bMonoDevice, - const CFX_DIBitmap* pBitmap, - int dest_left, - int dest_top, - int dest_width, - int dest_height, - FX_DWORD argb, - const FX_RECT* pClipRect, - int flags) { - ASSERT(pBitmap->GetBPP() == 1); - CGdiplusExt& GdiplusExt = - ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - GpGraphics* pGraphics = NULL; - CallFunc(GdipCreateFromHDC)(hDC, &pGraphics); - CallFunc(GdipSetPageUnit)(pGraphics, UnitPixel); - if (flags & FXDIB_NOSMOOTH) { - CallFunc(GdipSetInterpolationMode)(pGraphics, - InterpolationModeNearestNeighbor); - } else { - CallFunc(GdipSetInterpolationMode)(pGraphics, InterpolationModeHighQuality); - } - OutputImageMask(pGraphics, bMonoDevice, pBitmap, dest_left, dest_top, - dest_width, dest_height, argb, pClipRect); - CallFunc(GdipDeleteGraphics)(pGraphics); - return TRUE; -} -FX_BOOL CGdiplusExt::StretchDIBits(HDC hDC, - const CFX_DIBitmap* pBitmap, - int dest_left, - int dest_top, - int dest_width, - int dest_height, - const FX_RECT* pClipRect, - int flags) { - GpGraphics* pGraphics; - CGdiplusExt& GdiplusExt = - ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - CallFunc(GdipCreateFromHDC)(hDC, &pGraphics); - CallFunc(GdipSetPageUnit)(pGraphics, UnitPixel); - if (flags & FXDIB_NOSMOOTH) { - CallFunc(GdipSetInterpolationMode)(pGraphics, - InterpolationModeNearestNeighbor); - } else if (pBitmap->GetWidth() > abs(dest_width) / 2 || - pBitmap->GetHeight() > abs(dest_height) / 2) { - CallFunc(GdipSetInterpolationMode)(pGraphics, InterpolationModeHighQuality); - } else { - CallFunc(GdipSetInterpolationMode)(pGraphics, InterpolationModeBilinear); - } - FX_RECT src_rect(0, 0, pBitmap->GetWidth(), pBitmap->GetHeight()); - OutputImage(pGraphics, pBitmap, &src_rect, dest_left, dest_top, dest_width, - dest_height); - CallFunc(GdipDeleteGraphics)(pGraphics); - CallFunc(GdipDeleteGraphics)(pGraphics); - return TRUE; -} -static GpPen* _GdipCreatePen(const CFX_GraphStateData* pGraphState, - const CFX_Matrix* pMatrix, - DWORD argb, - FX_BOOL bTextMode = FALSE) { - CGdiplusExt& GdiplusExt = - ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - FX_FLOAT width = pGraphState ? pGraphState->m_LineWidth : 1.0f; - if (!bTextMode) { - FX_FLOAT unit = - pMatrix ? 1.0f / ((pMatrix->GetXUnit() + pMatrix->GetYUnit()) / 2) - : 1.0f; - if (width < unit) { - width = unit; - } - } - GpPen* pPen = NULL; - CallFunc(GdipCreatePen1)((ARGB)argb, width, UnitWorld, &pPen); - LineCap lineCap; - DashCap dashCap = DashCapFlat; - FX_BOOL bDashExtend = FALSE; - switch (pGraphState->m_LineCap) { - case CFX_GraphStateData::LineCapButt: - lineCap = LineCapFlat; - break; - case CFX_GraphStateData::LineCapRound: - lineCap = LineCapRound; - dashCap = DashCapRound; - bDashExtend = TRUE; - break; - case CFX_GraphStateData::LineCapSquare: - lineCap = LineCapSquare; - bDashExtend = TRUE; - break; - } - CallFunc(GdipSetPenLineCap197819)(pPen, lineCap, lineCap, dashCap); - LineJoin lineJoin; - switch (pGraphState->m_LineJoin) { - case CFX_GraphStateData::LineJoinMiter: - lineJoin = LineJoinMiterClipped; - break; - case CFX_GraphStateData::LineJoinRound: - lineJoin = LineJoinRound; - break; - case CFX_GraphStateData::LineJoinBevel: - lineJoin = LineJoinBevel; - break; - } - CallFunc(GdipSetPenLineJoin)(pPen, lineJoin); - if (pGraphState->m_DashCount) { - FX_FLOAT* pDashArray = FX_Alloc( - FX_FLOAT, pGraphState->m_DashCount + pGraphState->m_DashCount % 2); - int nCount = 0; - FX_FLOAT on_leftover = 0, off_leftover = 0; - for (int i = 0; i < pGraphState->m_DashCount; i += 2) { - FX_FLOAT on_phase = pGraphState->m_DashArray[i]; - FX_FLOAT off_phase; - if (i == pGraphState->m_DashCount - 1) { - off_phase = on_phase; - } else { - off_phase = pGraphState->m_DashArray[i + 1]; - } - on_phase /= width; - off_phase /= width; - if (on_phase + off_phase <= 0.00002f) { - on_phase = 1.0f / 10; - off_phase = 1.0f / 10; - } - if (bDashExtend) { - if (off_phase < 1) { - off_phase = 0; - } else { - off_phase -= 1; - } - on_phase += 1; - } - if (on_phase == 0 || off_phase == 0) { - if (nCount == 0) { - on_leftover += on_phase; - off_leftover += off_phase; - } else { - pDashArray[nCount - 2] += on_phase; - pDashArray[nCount - 1] += off_phase; - } - } else { - pDashArray[nCount++] = on_phase + on_leftover; - on_leftover = 0; - pDashArray[nCount++] = off_phase + off_leftover; - off_leftover = 0; - } - } - CallFunc(GdipSetPenDashArray)(pPen, pDashArray, nCount); - FX_FLOAT phase = pGraphState->m_DashPhase; - if (bDashExtend) { - if (phase < 0.5f) { - phase = 0; - } else { - phase -= 0.5f; - } - } - CallFunc(GdipSetPenDashOffset)(pPen, phase); - FX_Free(pDashArray); - pDashArray = NULL; - } - CallFunc(GdipSetPenMiterLimit)(pPen, pGraphState->m_MiterLimit); - return pPen; -} -static FX_BOOL IsSmallTriangle(PointF* points, - const CFX_Matrix* pMatrix, - int& v1, - int& v2) { - int pairs[] = {1, 2, 0, 2, 0, 1}; - for (int i = 0; i < 3; i++) { - int pair1 = pairs[i * 2]; - int pair2 = pairs[i * 2 + 1]; - FX_FLOAT x1 = points[pair1].X, x2 = points[pair2].X; - FX_FLOAT y1 = points[pair1].Y, y2 = points[pair2].Y; - if (pMatrix) { - pMatrix->Transform(x1, y1); - pMatrix->Transform(x2, y2); - } - FX_FLOAT dx = x1 - x2; - FX_FLOAT dy = y1 - y2; - FX_FLOAT distance_square = (dx * dx) + (dy * dy); - if (distance_square < (1.0f * 2 + 1.0f / 4)) { - v1 = i; - v2 = pair1; - return TRUE; - } - } - return FALSE; -} -FX_BOOL CGdiplusExt::DrawPath(HDC hDC, - const CFX_PathData* pPathData, - const CFX_Matrix* pObject2Device, - const CFX_GraphStateData* pGraphState, - FX_DWORD fill_argb, - FX_DWORD stroke_argb, - int fill_mode) { - int nPoints = pPathData->GetPointCount(); - if (nPoints == 0) { - return TRUE; - } - FX_PATHPOINT* pPoints = pPathData->GetPoints(); - GpGraphics* pGraphics = NULL; - CGdiplusExt& GdiplusExt = - ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - CallFunc(GdipCreateFromHDC)(hDC, &pGraphics); - CallFunc(GdipSetPageUnit)(pGraphics, UnitPixel); - CallFunc(GdipSetPixelOffsetMode)(pGraphics, PixelOffsetModeHalf); - GpMatrix* pMatrix = NULL; - if (pObject2Device) { - CallFunc(GdipCreateMatrix2)(pObject2Device->a, pObject2Device->b, - pObject2Device->c, pObject2Device->d, - pObject2Device->e, pObject2Device->f, &pMatrix); - CallFunc(GdipSetWorldTransform)(pGraphics, pMatrix); - } - PointF* points = FX_Alloc(PointF, nPoints); - BYTE* types = FX_Alloc(BYTE, nPoints); - int nSubPathes = 0; - FX_BOOL bSubClose = FALSE; - int pos_subclose = 0; - FX_BOOL bSmooth = FALSE; - int startpoint = 0; - for (int i = 0; i < nPoints; i++) { - points[i].X = pPoints[i].m_PointX; - points[i].Y = pPoints[i].m_PointY; - FX_FLOAT x, y; - if (pObject2Device) { - pObject2Device->Transform(pPoints[i].m_PointX, pPoints[i].m_PointY, x, y); - } else { - x = pPoints[i].m_PointX; - y = pPoints[i].m_PointY; - } - if (x > 50000 * 1.0f) { - points[i].X = 50000 * 1.0f; - } - if (x < -50000 * 1.0f) { - points[i].X = -50000 * 1.0f; - } - if (y > 50000 * 1.0f) { - points[i].Y = 50000 * 1.0f; - } - if (y < -50000 * 1.0f) { - points[i].Y = -50000 * 1.0f; - } - int point_type = pPoints[i].m_Flag & FXPT_TYPE; - if (point_type == FXPT_MOVETO) { - types[i] = PathPointTypeStart; - nSubPathes++; - bSubClose = FALSE; - startpoint = i; - } else if (point_type == FXPT_LINETO) { - types[i] = PathPointTypeLine; - if (pPoints[i - 1].m_Flag == FXPT_MOVETO && - (i == nPoints - 1 || pPoints[i + 1].m_Flag == FXPT_MOVETO) && - points[i].Y == points[i - 1].Y && points[i].X == points[i - 1].X) { - points[i].X += 0.01f; - continue; - } - if (!bSmooth && points[i].X != points[i - 1].X && - points[i].Y != points[i - 1].Y) { - bSmooth = TRUE; - } - } else if (point_type == FXPT_BEZIERTO) { - types[i] = PathPointTypeBezier; - bSmooth = TRUE; - } - if (pPoints[i].m_Flag & FXPT_CLOSEFIGURE) { - if (bSubClose) { - types[pos_subclose] &= ~PathPointTypeCloseSubpath; - } else { - bSubClose = TRUE; - } - pos_subclose = i; - types[i] |= PathPointTypeCloseSubpath; - if (!bSmooth && points[i].X != points[startpoint].X && - points[i].Y != points[startpoint].Y) { - bSmooth = TRUE; - } - } - } - if (fill_mode & FXFILL_NOPATHSMOOTH) { - bSmooth = FALSE; - CallFunc(GdipSetSmoothingMode)(pGraphics, SmoothingModeNone); - } else if (!(fill_mode & FXFILL_FULLCOVER)) { - if (!bSmooth && (fill_mode & 3)) { - bSmooth = TRUE; - } - if (bSmooth || (pGraphState && pGraphState->m_LineWidth > 2)) { - CallFunc(GdipSetSmoothingMode)(pGraphics, SmoothingModeAntiAlias); - } - } - int new_fill_mode = fill_mode & 3; - if (nPoints == 4 && !pGraphState) { - int v1, v2; - if (IsSmallTriangle(points, pObject2Device, v1, v2)) { - GpPen* pPen = NULL; - CallFunc(GdipCreatePen1)(fill_argb, 1.0f, UnitPixel, &pPen); - CallFunc(GdipDrawLineI)( - pGraphics, pPen, FXSYS_round(points[v1].X), FXSYS_round(points[v1].Y), - FXSYS_round(points[v2].X), FXSYS_round(points[v2].Y)); - CallFunc(GdipDeletePen)(pPen); - return TRUE; - } - } - GpPath* pGpPath = NULL; - CallFunc(GdipCreatePath2)(points, types, nPoints, - GdiFillType2Gdip(new_fill_mode), &pGpPath); - if (!pGpPath) { - if (pMatrix) { - CallFunc(GdipDeleteMatrix)(pMatrix); - } - FX_Free(points); - FX_Free(types); - CallFunc(GdipDeleteGraphics)(pGraphics); - return FALSE; - } - if (new_fill_mode) { - GpBrush* pBrush = _GdipCreateBrush(fill_argb); - CallFunc(GdipSetPathFillMode)(pGpPath, GdiFillType2Gdip(new_fill_mode)); - CallFunc(GdipFillPath)(pGraphics, pBrush, pGpPath); - CallFunc(GdipDeleteBrush)(pBrush); - } - if (pGraphState && stroke_argb) { - GpPen* pPen = _GdipCreatePen(pGraphState, pObject2Device, stroke_argb, - fill_mode & FX_STROKE_TEXT_MODE); - if (nSubPathes == 1) { - CallFunc(GdipDrawPath)(pGraphics, pPen, pGpPath); - } else { - int iStart = 0; - for (int i = 0; i < nPoints; i++) { - if (i == nPoints - 1 || types[i + 1] == PathPointTypeStart) { - GpPath* pSubPath; - CallFunc(GdipCreatePath2)(points + iStart, types + iStart, - i - iStart + 1, - GdiFillType2Gdip(new_fill_mode), &pSubPath); - iStart = i + 1; - CallFunc(GdipDrawPath)(pGraphics, pPen, pSubPath); - CallFunc(GdipDeletePath)(pSubPath); - } - } - } - CallFunc(GdipDeletePen)(pPen); - } - if (pMatrix) { - CallFunc(GdipDeleteMatrix)(pMatrix); - } - FX_Free(points); - FX_Free(types); - CallFunc(GdipDeletePath)(pGpPath); - CallFunc(GdipDeleteGraphics)(pGraphics); - return TRUE; -} -class GpStream final : public IStream { - LONG m_RefCount; - int m_ReadPos; - CFX_ByteTextBuf m_InterStream; - - public: - GpStream() { - m_RefCount = 1; - m_ReadPos = 0; - } - virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, - void** ppvObject) { - if (iid == __uuidof(IUnknown) || iid == __uuidof(IStream) || - iid == __uuidof(ISequentialStream)) { - *ppvObject = static_cast<IStream*>(this); - AddRef(); - return S_OK; - } - return E_NOINTERFACE; - } - virtual ULONG STDMETHODCALLTYPE AddRef(void) { - return (ULONG)InterlockedIncrement(&m_RefCount); - } - virtual ULONG STDMETHODCALLTYPE Release(void) { - ULONG res = (ULONG)InterlockedDecrement(&m_RefCount); - if (res == 0) { - delete this; - } - return res; - } - - public: - virtual HRESULT STDMETHODCALLTYPE Read(void* Output, - ULONG cb, - ULONG* pcbRead) { - size_t bytes_left; - size_t bytes_out; - if (pcbRead) { - *pcbRead = 0; - } - if (m_ReadPos == m_InterStream.GetLength()) { - return HRESULT_FROM_WIN32(ERROR_END_OF_MEDIA); - } - bytes_left = m_InterStream.GetLength() - m_ReadPos; - bytes_out = std::min(pdfium::base::checked_cast<size_t>(cb), bytes_left); - FXSYS_memcpy(Output, m_InterStream.GetBuffer() + m_ReadPos, bytes_out); - m_ReadPos += (int32_t)bytes_out; - if (pcbRead) { - *pcbRead = (ULONG)bytes_out; - } - return S_OK; - } - virtual HRESULT STDMETHODCALLTYPE Write(void const* Input, - ULONG cb, - ULONG* pcbWritten) { - if (cb <= 0) { - if (pcbWritten) { - *pcbWritten = 0; - } - return S_OK; - } - m_InterStream.InsertBlock(m_InterStream.GetLength(), Input, cb); - if (pcbWritten) { - *pcbWritten = cb; - } - return S_OK; - } - - public: - virtual HRESULT STDMETHODCALLTYPE SetSize(ULARGE_INTEGER) { - return E_NOTIMPL; - } - virtual HRESULT STDMETHODCALLTYPE CopyTo(IStream*, - ULARGE_INTEGER, - ULARGE_INTEGER*, - ULARGE_INTEGER*) { - return E_NOTIMPL; - } - virtual HRESULT STDMETHODCALLTYPE Commit(DWORD) { return E_NOTIMPL; } - virtual HRESULT STDMETHODCALLTYPE Revert(void) { return E_NOTIMPL; } - virtual HRESULT STDMETHODCALLTYPE LockRegion(ULARGE_INTEGER, - ULARGE_INTEGER, - DWORD) { - return E_NOTIMPL; - } - virtual HRESULT STDMETHODCALLTYPE UnlockRegion(ULARGE_INTEGER, - ULARGE_INTEGER, - DWORD) { - return E_NOTIMPL; - } - virtual HRESULT STDMETHODCALLTYPE Clone(IStream** stream) { - return E_NOTIMPL; - } - virtual HRESULT STDMETHODCALLTYPE Seek(LARGE_INTEGER liDistanceToMove, - DWORD dwOrigin, - ULARGE_INTEGER* lpNewFilePointer) { - long start = 0; - long new_read_position; - switch (dwOrigin) { - case STREAM_SEEK_SET: - start = 0; - break; - case STREAM_SEEK_CUR: - start = m_ReadPos; - break; - case STREAM_SEEK_END: - start = m_InterStream.GetLength(); - break; - default: - return STG_E_INVALIDFUNCTION; - break; - } - new_read_position = start + (long)liDistanceToMove.QuadPart; - if (new_read_position < 0 || - new_read_position > m_InterStream.GetLength()) { - return STG_E_SEEKERROR; - } - m_ReadPos = new_read_position; - if (lpNewFilePointer) { - lpNewFilePointer->QuadPart = m_ReadPos; - } - return S_OK; - } - virtual HRESULT STDMETHODCALLTYPE Stat(STATSTG* pStatstg, DWORD grfStatFlag) { - if (!pStatstg) { - return STG_E_INVALIDFUNCTION; - } - ZeroMemory(pStatstg, sizeof(STATSTG)); - pStatstg->cbSize.QuadPart = m_InterStream.GetLength(); - return S_OK; - } -}; -typedef struct { - BITMAPINFO* pbmi; - int Stride; - LPBYTE pScan0; - GpBitmap* pBitmap; - BitmapData* pBitmapData; - GpStream* pStream; -} PREVIEW3_DIBITMAP; -static PREVIEW3_DIBITMAP* LoadDIBitmap(WINDIB_Open_Args_ args) { - GpBitmap* pBitmap; - GpStream* pStream = NULL; - CGdiplusExt& GdiplusExt = - ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - Status status = Ok; - if (args.flags == WINDIB_OPEN_PATHNAME) { - status = CallFunc(GdipCreateBitmapFromFileICM)((wchar_t*)args.path_name, - &pBitmap); - } else { - if (args.memory_size == 0 || !args.memory_base) { - return NULL; - } - pStream = new GpStream; - pStream->Write(args.memory_base, (ULONG)args.memory_size, NULL); - status = CallFunc(GdipCreateBitmapFromStreamICM)(pStream, &pBitmap); - } - if (status != Ok) { - if (pStream) { - pStream->Release(); - } - return NULL; - } - UINT height, width; - CallFunc(GdipGetImageHeight)(pBitmap, &height); - CallFunc(GdipGetImageWidth)(pBitmap, &width); - PixelFormat pixel_format; - CallFunc(GdipGetImagePixelFormat)(pBitmap, &pixel_format); - int info_size = sizeof(BITMAPINFOHEADER); - int bpp = 24; - int dest_pixel_format = PixelFormat24bppRGB; - if (pixel_format == PixelFormat1bppIndexed) { - info_size += 8; - bpp = 1; - dest_pixel_format = PixelFormat1bppIndexed; - } else if (pixel_format == PixelFormat8bppIndexed) { - info_size += 1024; - bpp = 8; - dest_pixel_format = PixelFormat8bppIndexed; - } else if (pixel_format == PixelFormat32bppARGB) { - bpp = 32; - dest_pixel_format = PixelFormat32bppARGB; - } - LPBYTE buf = FX_Alloc(BYTE, info_size); - BITMAPINFOHEADER* pbmih = (BITMAPINFOHEADER*)buf; - pbmih->biBitCount = bpp; - pbmih->biCompression = BI_RGB; - pbmih->biHeight = -(int)height; - pbmih->biPlanes = 1; - pbmih->biWidth = width; - Rect rect(0, 0, width, height); - BitmapData* pBitmapData = FX_Alloc(BitmapData, 1); - CallFunc(GdipBitmapLockBits)(pBitmap, &rect, ImageLockModeRead, - dest_pixel_format, pBitmapData); - if (pixel_format == PixelFormat1bppIndexed || - pixel_format == PixelFormat8bppIndexed) { - DWORD* ppal = (DWORD*)(buf + sizeof(BITMAPINFOHEADER)); - struct { - UINT flags; - UINT Count; - DWORD Entries[256]; - } pal; - int size = 0; - CallFunc(GdipGetImagePaletteSize)(pBitmap, &size); - CallFunc(GdipGetImagePalette)(pBitmap, (ColorPalette*)&pal, size); - int entries = pixel_format == PixelFormat1bppIndexed ? 2 : 256; - for (int i = 0; i < entries; i++) { - ppal[i] = pal.Entries[i] & 0x00ffffff; - } - } - PREVIEW3_DIBITMAP* pInfo = FX_Alloc(PREVIEW3_DIBITMAP, 1); - pInfo->pbmi = (BITMAPINFO*)buf; - pInfo->pScan0 = (LPBYTE)pBitmapData->Scan0; - pInfo->Stride = pBitmapData->Stride; - pInfo->pBitmap = pBitmap; - pInfo->pBitmapData = pBitmapData; - pInfo->pStream = pStream; - return pInfo; -} -static void FreeDIBitmap(PREVIEW3_DIBITMAP* pInfo) { - CGdiplusExt& GdiplusExt = - ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - CallFunc(GdipBitmapUnlockBits)(pInfo->pBitmap, pInfo->pBitmapData); - CallFunc(GdipDisposeImage)(pInfo->pBitmap); - FX_Free(pInfo->pBitmapData); - FX_Free((LPBYTE)pInfo->pbmi); - if (pInfo->pStream) { - pInfo->pStream->Release(); - } - FX_Free(pInfo); -} -CFX_DIBitmap* _FX_WindowsDIB_LoadFromBuf(BITMAPINFO* pbmi, - LPVOID pData, - FX_BOOL bAlpha); -CFX_DIBitmap* CGdiplusExt::LoadDIBitmap(WINDIB_Open_Args_ args) { - PREVIEW3_DIBITMAP* pInfo = ::LoadDIBitmap(args); - if (!pInfo) { - return NULL; - } - int height = abs(pInfo->pbmi->bmiHeader.biHeight); - int width = pInfo->pbmi->bmiHeader.biWidth; - int dest_pitch = (width * pInfo->pbmi->bmiHeader.biBitCount + 31) / 32 * 4; - LPBYTE pData = FX_Alloc2D(BYTE, dest_pitch, height); - if (dest_pitch == pInfo->Stride) { - FXSYS_memcpy(pData, pInfo->pScan0, dest_pitch * height); - } else { - for (int i = 0; i < height; i++) { - FXSYS_memcpy(pData + dest_pitch * i, pInfo->pScan0 + pInfo->Stride * i, - dest_pitch); - } - } - CFX_DIBitmap* pDIBitmap = _FX_WindowsDIB_LoadFromBuf( - pInfo->pbmi, pData, pInfo->pbmi->bmiHeader.biBitCount == 32); - FX_Free(pData); - FreeDIBitmap(pInfo); - return pDIBitmap; -} -#endif |