Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(127)

Side by Side Diff: core/src/fxge/win32/fx_win32_gdipext.cpp

Issue 1265503005: clang-format all pdfium code. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: sigh Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 PDFium Authors. All rights reserved. 1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 6
7 #include "../../../include/fxge/fx_ge.h" 7 #include "../../../include/fxge/fx_ge.h"
8 #if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_DESKTOP_ 8 #if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_DESKTOP_
9 #include <windows.h> 9 #include <windows.h>
10 #include <algorithm> 10 #include <algorithm>
11 namespace Gdiplus { 11 namespace Gdiplus {
12 using std::min; 12 using std::min;
13 using std::max; 13 using std::max;
14 } // namespace Gdiplus 14 } // namespace Gdiplus
15 #include <gdiplus.h> 15 #include <gdiplus.h>
16 #include "../../../include/fxge/fx_ge_win32.h" 16 #include "../../../include/fxge/fx_ge_win32.h"
17 #include "win32_int.h" 17 #include "win32_int.h"
18 using namespace Gdiplus; 18 using namespace Gdiplus;
19 using namespace Gdiplus::DllExports; 19 using namespace Gdiplus::DllExports;
20 #define GdiFillType2Gdip(fill_type) (fill_type == ALTERNATE ? FillModeAlternate : FillModeWinding) 20 #define GdiFillType2Gdip(fill_type) \
21 static CombineMode GdiCombineMode2Gdip(int mode) 21 (fill_type == ALTERNATE ? FillModeAlternate : FillModeWinding)
22 { 22 static CombineMode GdiCombineMode2Gdip(int mode) {
23 switch (mode) { 23 switch (mode) {
24 case RGN_AND: 24 case RGN_AND:
25 return CombineModeIntersect; 25 return CombineModeIntersect;
26 } 26 }
27 return CombineModeIntersect; 27 return CombineModeIntersect;
28 } 28 }
29 enum { 29 enum {
30 FuncId_GdipCreatePath2, 30 FuncId_GdipCreatePath2,
31 FuncId_GdipSetPenDashStyle, 31 FuncId_GdipSetPenDashStyle,
32 FuncId_GdipSetPenDashArray, 32 FuncId_GdipSetPenDashArray,
33 FuncId_GdipSetPenDashCap197819, 33 FuncId_GdipSetPenDashCap197819,
34 FuncId_GdipSetPenLineJoin, 34 FuncId_GdipSetPenLineJoin,
35 FuncId_GdipSetPenWidth, 35 FuncId_GdipSetPenWidth,
36 FuncId_GdipCreateFromHDC, 36 FuncId_GdipCreateFromHDC,
37 FuncId_GdipSetPageUnit, 37 FuncId_GdipSetPageUnit,
38 FuncId_GdipSetSmoothingMode, 38 FuncId_GdipSetSmoothingMode,
39 FuncId_GdipCreateSolidFill, 39 FuncId_GdipCreateSolidFill,
40 FuncId_GdipFillPath, 40 FuncId_GdipFillPath,
41 FuncId_GdipDeleteBrush, 41 FuncId_GdipDeleteBrush,
42 FuncId_GdipCreatePen1, 42 FuncId_GdipCreatePen1,
43 FuncId_GdipSetPenMiterLimit, 43 FuncId_GdipSetPenMiterLimit,
44 FuncId_GdipDrawPath, 44 FuncId_GdipDrawPath,
45 FuncId_GdipDeletePen, 45 FuncId_GdipDeletePen,
46 FuncId_GdipDeletePath, 46 FuncId_GdipDeletePath,
47 FuncId_GdipDeleteGraphics, 47 FuncId_GdipDeleteGraphics,
48 FuncId_GdipCreateBitmapFromFileICM, 48 FuncId_GdipCreateBitmapFromFileICM,
49 FuncId_GdipCreateBitmapFromStreamICM, 49 FuncId_GdipCreateBitmapFromStreamICM,
50 FuncId_GdipGetImageHeight, 50 FuncId_GdipGetImageHeight,
51 FuncId_GdipGetImageWidth, 51 FuncId_GdipGetImageWidth,
52 FuncId_GdipGetImagePixelFormat, 52 FuncId_GdipGetImagePixelFormat,
53 FuncId_GdipBitmapLockBits, 53 FuncId_GdipBitmapLockBits,
54 FuncId_GdipGetImagePaletteSize, 54 FuncId_GdipGetImagePaletteSize,
55 FuncId_GdipGetImagePalette, 55 FuncId_GdipGetImagePalette,
56 FuncId_GdipBitmapUnlockBits, 56 FuncId_GdipBitmapUnlockBits,
57 FuncId_GdipDisposeImage, 57 FuncId_GdipDisposeImage,
58 FuncId_GdipFillRectangle, 58 FuncId_GdipFillRectangle,
59 FuncId_GdipCreateBitmapFromScan0, 59 FuncId_GdipCreateBitmapFromScan0,
60 FuncId_GdipSetImagePalette, 60 FuncId_GdipSetImagePalette,
61 FuncId_GdipSetInterpolationMode, 61 FuncId_GdipSetInterpolationMode,
62 FuncId_GdipDrawImagePointsI, 62 FuncId_GdipDrawImagePointsI,
63 FuncId_GdipCreateBitmapFromGdiDib, 63 FuncId_GdipCreateBitmapFromGdiDib,
64 FuncId_GdiplusStartup, 64 FuncId_GdiplusStartup,
65 FuncId_GdipDrawLineI, 65 FuncId_GdipDrawLineI,
66 FuncId_GdipResetClip, 66 FuncId_GdipResetClip,
67 FuncId_GdipCreatePath, 67 FuncId_GdipCreatePath,
68 FuncId_GdipAddPathPath, 68 FuncId_GdipAddPathPath,
69 FuncId_GdipSetPathFillMode, 69 FuncId_GdipSetPathFillMode,
70 FuncId_GdipSetClipPath, 70 FuncId_GdipSetClipPath,
71 FuncId_GdipGetClip, 71 FuncId_GdipGetClip,
72 FuncId_GdipCreateRegion, 72 FuncId_GdipCreateRegion,
73 FuncId_GdipGetClipBoundsI, 73 FuncId_GdipGetClipBoundsI,
74 FuncId_GdipSetClipRegion, 74 FuncId_GdipSetClipRegion,
75 FuncId_GdipWidenPath, 75 FuncId_GdipWidenPath,
76 FuncId_GdipAddPathLine, 76 FuncId_GdipAddPathLine,
77 FuncId_GdipAddPathRectangle, 77 FuncId_GdipAddPathRectangle,
78 FuncId_GdipDeleteRegion, 78 FuncId_GdipDeleteRegion,
79 FuncId_GdipGetDC, 79 FuncId_GdipGetDC,
80 FuncId_GdipReleaseDC, 80 FuncId_GdipReleaseDC,
81 FuncId_GdipSetPenLineCap197819, 81 FuncId_GdipSetPenLineCap197819,
82 FuncId_GdipSetPenDashOffset, 82 FuncId_GdipSetPenDashOffset,
83 FuncId_GdipResetPath, 83 FuncId_GdipResetPath,
84 FuncId_GdipCreateRegionPath, 84 FuncId_GdipCreateRegionPath,
85 FuncId_GdipCreateFont, 85 FuncId_GdipCreateFont,
86 FuncId_GdipGetFontSize, 86 FuncId_GdipGetFontSize,
87 FuncId_GdipCreateFontFamilyFromName, 87 FuncId_GdipCreateFontFamilyFromName,
88 FuncId_GdipSetTextRenderingHint, 88 FuncId_GdipSetTextRenderingHint,
89 FuncId_GdipDrawDriverString, 89 FuncId_GdipDrawDriverString,
90 FuncId_GdipCreateMatrix2, 90 FuncId_GdipCreateMatrix2,
91 FuncId_GdipDeleteMatrix, 91 FuncId_GdipDeleteMatrix,
92 FuncId_GdipSetWorldTransform, 92 FuncId_GdipSetWorldTransform,
93 FuncId_GdipResetWorldTransform, 93 FuncId_GdipResetWorldTransform,
94 FuncId_GdipDeleteFontFamily, 94 FuncId_GdipDeleteFontFamily,
95 FuncId_GdipDeleteFont, 95 FuncId_GdipDeleteFont,
96 FuncId_GdipNewPrivateFontCollection, 96 FuncId_GdipNewPrivateFontCollection,
97 FuncId_GdipDeletePrivateFontCollection, 97 FuncId_GdipDeletePrivateFontCollection,
98 FuncId_GdipPrivateAddMemoryFont, 98 FuncId_GdipPrivateAddMemoryFont,
99 FuncId_GdipGetFontCollectionFamilyList, 99 FuncId_GdipGetFontCollectionFamilyList,
100 FuncId_GdipGetFontCollectionFamilyCount, 100 FuncId_GdipGetFontCollectionFamilyCount,
101 FuncId_GdipSetTextContrast, 101 FuncId_GdipSetTextContrast,
102 FuncId_GdipSetPixelOffsetMode, 102 FuncId_GdipSetPixelOffsetMode,
103 FuncId_GdipGetImageGraphicsContext, 103 FuncId_GdipGetImageGraphicsContext,
104 FuncId_GdipDrawImageI, 104 FuncId_GdipDrawImageI,
105 FuncId_GdipDrawImageRectI, 105 FuncId_GdipDrawImageRectI,
106 FuncId_GdipDrawString, 106 FuncId_GdipDrawString,
107 FuncId_GdipSetPenTransform, 107 FuncId_GdipSetPenTransform,
108 }; 108 };
109 static LPCSTR g_GdipFuncNames[] = { 109 static LPCSTR g_GdipFuncNames[] = {
110 "GdipCreatePath2", 110 "GdipCreatePath2",
111 "GdipSetPenDashStyle", 111 "GdipSetPenDashStyle",
112 "GdipSetPenDashArray", 112 "GdipSetPenDashArray",
113 "GdipSetPenDashCap197819", 113 "GdipSetPenDashCap197819",
114 "GdipSetPenLineJoin", 114 "GdipSetPenLineJoin",
115 "GdipSetPenWidth", 115 "GdipSetPenWidth",
116 "GdipCreateFromHDC", 116 "GdipCreateFromHDC",
117 "GdipSetPageUnit", 117 "GdipSetPageUnit",
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 "GdipGetFontCollectionFamilyList", 179 "GdipGetFontCollectionFamilyList",
180 "GdipGetFontCollectionFamilyCount", 180 "GdipGetFontCollectionFamilyCount",
181 "GdipSetTextContrast", 181 "GdipSetTextContrast",
182 "GdipSetPixelOffsetMode", 182 "GdipSetPixelOffsetMode",
183 "GdipGetImageGraphicsContext", 183 "GdipGetImageGraphicsContext",
184 "GdipDrawImageI", 184 "GdipDrawImageI",
185 "GdipDrawImageRectI", 185 "GdipDrawImageRectI",
186 "GdipDrawString", 186 "GdipDrawString",
187 "GdipSetPenTransform", 187 "GdipSetPenTransform",
188 }; 188 };
189 typedef GpStatus (WINGDIPAPI *FuncType_GdipCreatePath2)(GDIPCONST GpPointF*, GDI PCONST BYTE*, INT, GpFillMode, GpPath **path); 189 typedef GpStatus(WINGDIPAPI* FuncType_GdipCreatePath2)(GDIPCONST GpPointF*,
190 typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenDashStyle)(GpPen *pen, GpDashSt yle dashstyle); 190 GDIPCONST BYTE*,
191 typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenDashArray)(GpPen *pen, GDIPCONS T REAL *dash, INT count); 191 INT,
192 typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenDashCap197819)(GpPen *pen, GpDa shCap dashCap); 192 GpFillMode,
193 typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenLineJoin)(GpPen *pen, GpLineJoi n lineJoin); 193 GpPath** path);
194 typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenWidth)(GpPen *pen, REAL width); 194 typedef GpStatus(WINGDIPAPI* FuncType_GdipSetPenDashStyle)(
195 typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateFromHDC)(HDC hdc, GpGraphics ** graphics); 195 GpPen* pen,
196 typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPageUnit)(GpGraphics *graphics, Gp Unit unit); 196 GpDashStyle dashstyle);
197 typedef GpStatus (WINGDIPAPI *FuncType_GdipSetSmoothingMode)(GpGraphics *graphic s, SmoothingMode smoothingMode); 197 typedef GpStatus(WINGDIPAPI* FuncType_GdipSetPenDashArray)(GpPen* pen,
198 typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateSolidFill)(ARGB color, GpSolidF ill **brush); 198 GDIPCONST REAL* dash,
199 typedef GpStatus (WINGDIPAPI *FuncType_GdipFillPath)(GpGraphics *graphics, GpBru sh *brush, GpPath *path); 199 INT count);
200 typedef GpStatus (WINGDIPAPI *FuncType_GdipDeleteBrush)(GpBrush *brush); 200 typedef GpStatus(WINGDIPAPI* FuncType_GdipSetPenDashCap197819)(
201 typedef GpStatus (WINGDIPAPI *FuncType_GdipCreatePen1)(ARGB color, REAL width, G pUnit unit, GpPen **pen); 201 GpPen* pen,
202 typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenMiterLimit)(GpPen *pen, REAL mi terLimit); 202 GpDashCap dashCap);
203 typedef GpStatus (WINGDIPAPI *FuncType_GdipDrawPath)(GpGraphics *graphics, GpPen *pen, GpPath *path); 203 typedef GpStatus(WINGDIPAPI* FuncType_GdipSetPenLineJoin)(GpPen* pen,
204 typedef GpStatus (WINGDIPAPI *FuncType_GdipDeletePen)(GpPen *pen); 204 GpLineJoin lineJoin);
205 typedef GpStatus (WINGDIPAPI *FuncType_GdipDeletePath)(GpPath* path); 205 typedef GpStatus(WINGDIPAPI* FuncType_GdipSetPenWidth)(GpPen* pen, REAL width);
206 typedef GpStatus (WINGDIPAPI *FuncType_GdipDeleteGraphics)(GpGraphics *graphics) ; 206 typedef GpStatus(WINGDIPAPI* FuncType_GdipCreateFromHDC)(HDC hdc,
207 typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateBitmapFromFileICM)(GDIPCONST WC HAR* filename, GpBitmap **bitmap); 207 GpGraphics** graphics);
208 typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateBitmapFromStreamICM)(IStream* s tream, GpBitmap **bitmap); 208 typedef GpStatus(WINGDIPAPI* FuncType_GdipSetPageUnit)(GpGraphics* graphics,
209 typedef GpStatus (WINGDIPAPI *FuncType_GdipGetImageWidth)(GpImage *image, UINT * width); 209 GpUnit unit);
210 typedef GpStatus (WINGDIPAPI *FuncType_GdipGetImageHeight)(GpImage *image, UINT *height); 210 typedef GpStatus(WINGDIPAPI* FuncType_GdipSetSmoothingMode)(
211 typedef GpStatus (WINGDIPAPI *FuncType_GdipGetImagePixelFormat)(GpImage *image, PixelFormat *format); 211 GpGraphics* graphics,
212 typedef GpStatus (WINGDIPAPI *FuncType_GdipBitmapLockBits)(GpBitmap* bitmap, GDI PCONST GpRect* rect, UINT flags, PixelFormat format, BitmapData* lockedBitmapDat a); 212 SmoothingMode smoothingMode);
213 typedef GpStatus (WINGDIPAPI *FuncType_GdipGetImagePalette)(GpImage *image, Colo rPalette *palette, INT size); 213 typedef GpStatus(WINGDIPAPI* FuncType_GdipCreateSolidFill)(ARGB color,
214 typedef GpStatus (WINGDIPAPI *FuncType_GdipGetImagePaletteSize)(GpImage *image, INT *size); 214 GpSolidFill** brush);
215 typedef GpStatus (WINGDIPAPI *FuncType_GdipBitmapUnlockBits)(GpBitmap* bitmap, B itmapData* lockedBitmapData); 215 typedef GpStatus(WINGDIPAPI* FuncType_GdipFillPath)(GpGraphics* graphics,
216 typedef GpStatus (WINGDIPAPI *FuncType_GdipDisposeImage)(GpImage *image); 216 GpBrush* brush,
217 typedef GpStatus (WINGDIPAPI *FuncType_GdipFillRectangle)(GpGraphics *graphics, GpBrush *brush, REAL x, REAL y, REAL width, REAL height); 217 GpPath* path);
218 typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateBitmapFromScan0)(INT width, INT height, INT stride, PixelFormat format, BYTE* scan0, GpBitmap** bitmap); 218 typedef GpStatus(WINGDIPAPI* FuncType_GdipDeleteBrush)(GpBrush* brush);
219 typedef GpStatus (WINGDIPAPI *FuncType_GdipSetImagePalette)(GpImage *image, GDIP CONST ColorPalette *palette); 219 typedef GpStatus(WINGDIPAPI* FuncType_GdipCreatePen1)(ARGB color,
220 typedef GpStatus (WINGDIPAPI *FuncType_GdipSetInterpolationMode)(GpGraphics *gra phics, InterpolationMode interpolationMode); 220 REAL width,
221 typedef GpStatus (WINGDIPAPI *FuncType_GdipDrawImagePointsI)(GpGraphics *graphic s, GpImage *image, GDIPCONST GpPoint *dstpoints, INT count); 221 GpUnit unit,
222 typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateBitmapFromGdiDib)(GDIPCONST BIT MAPINFO* gdiBitmapInfo, VOID* gdiBitmapData, GpBitmap** bitmap); 222 GpPen** pen);
223 typedef Status (WINAPI *FuncType_GdiplusStartup)(OUT uintptr_t *token, const Gdi plusStartupInput *input, OUT GdiplusStartupOutput *output); 223 typedef GpStatus(WINGDIPAPI* FuncType_GdipSetPenMiterLimit)(GpPen* pen,
224 typedef GpStatus (WINGDIPAPI *FuncType_GdipDrawLineI)(GpGraphics *graphics, GpPe n *pen, int x1, int y1, int x2, int y2); 224 REAL miterLimit);
225 typedef GpStatus (WINGDIPAPI *FuncType_GdipResetClip)(GpGraphics *graphics); 225 typedef GpStatus(WINGDIPAPI* FuncType_GdipDrawPath)(GpGraphics* graphics,
226 typedef GpStatus (WINGDIPAPI *FuncType_GdipCreatePath)(GpFillMode brushMode, GpP ath **path); 226 GpPen* pen,
227 typedef GpStatus (WINGDIPAPI *FuncType_GdipAddPathPath)(GpPath *path, GDIPCONST GpPath* addingPath, BOOL connect); 227 GpPath* path);
228 typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPathFillMode)(GpPath *path, GpFill Mode fillmode); 228 typedef GpStatus(WINGDIPAPI* FuncType_GdipDeletePen)(GpPen* pen);
229 typedef GpStatus (WINGDIPAPI *FuncType_GdipSetClipPath)(GpGraphics *graphics, Gp Path *path, CombineMode combineMode); 229 typedef GpStatus(WINGDIPAPI* FuncType_GdipDeletePath)(GpPath* path);
230 typedef GpStatus (WINGDIPAPI *FuncType_GdipGetClip)(GpGraphics *graphics, GpRegi on *region); 230 typedef GpStatus(WINGDIPAPI* FuncType_GdipDeleteGraphics)(GpGraphics* graphics);
231 typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateRegion)(GpRegion **region); 231 typedef GpStatus(WINGDIPAPI* FuncType_GdipCreateBitmapFromFileICM)(
232 typedef GpStatus (WINGDIPAPI *FuncType_GdipGetClipBoundsI)(GpGraphics *graphics, GpRect *rect); 232 GDIPCONST WCHAR* filename,
233 typedef GpStatus (WINGDIPAPI *FuncType_GdipSetClipRegion)(GpGraphics *graphics, GpRegion *region, CombineMode combineMode); 233 GpBitmap** bitmap);
234 typedef GpStatus (WINGDIPAPI *FuncType_GdipWidenPath)(GpPath *nativePath, GpPen *pen, GpMatrix *matrix, REAL flatness); 234 typedef GpStatus(WINGDIPAPI* FuncType_GdipCreateBitmapFromStreamICM)(
235 typedef GpStatus (WINGDIPAPI *FuncType_GdipAddPathLine)(GpPath *path, REAL x1, R EAL y1, REAL x2, REAL y2); 235 IStream* stream,
236 typedef GpStatus (WINGDIPAPI *FuncType_GdipAddPathRectangle)(GpPath *path, REAL x, REAL y, REAL width, REAL height); 236 GpBitmap** bitmap);
237 typedef GpStatus (WINGDIPAPI *FuncType_GdipDeleteRegion)(GpRegion *region); 237 typedef GpStatus(WINGDIPAPI* FuncType_GdipGetImageWidth)(GpImage* image,
238 typedef GpStatus (WINGDIPAPI *FuncType_GdipGetDC)(GpGraphics* graphics, HDC * hd c); 238 UINT* width);
239 typedef GpStatus (WINGDIPAPI *FuncType_GdipReleaseDC)(GpGraphics* graphics, HDC hdc); 239 typedef GpStatus(WINGDIPAPI* FuncType_GdipGetImageHeight)(GpImage* image,
240 typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenLineCap197819)(GpPen *pen, GpLi neCap startCap, GpLineCap endCap, GpDashCap dashCap); 240 UINT* height);
241 typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenDashOffset)(GpPen *pen, REAL of fset); 241 typedef GpStatus(WINGDIPAPI* FuncType_GdipGetImagePixelFormat)(
242 typedef GpStatus (WINGDIPAPI *FuncType_GdipResetPath)(GpPath *path); 242 GpImage* image,
243 typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateRegionPath)(GpPath *path, GpReg ion **region); 243 PixelFormat* format);
244 typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateFont)(GDIPCONST GpFontFamily *f ontFamily, REAL emSize, INT style, Unit unit, GpFont **font); 244 typedef GpStatus(WINGDIPAPI* FuncType_GdipBitmapLockBits)(
245 typedef GpStatus (WINGDIPAPI *FuncType_GdipGetFontSize)(GpFont *font, REAL *size ); 245 GpBitmap* bitmap,
246 typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateFontFamilyFromName)(GDIPCONST W CHAR *name, GpFontCollection *fontCollection, GpFontFamily **FontFamily); 246 GDIPCONST GpRect* rect,
247 typedef GpStatus (WINGDIPAPI *FuncType_GdipSetTextRenderingHint)(GpGraphics *gra phics, TextRenderingHint mode); 247 UINT flags,
248 typedef GpStatus (WINGDIPAPI *FuncType_GdipDrawDriverString)(GpGraphics *graphic s, GDIPCONST UINT16 *text, INT length, GDIPCONST GpFont *font, GDIPCONST GpBrush *brush, GDIPCONST PointF *positions, INT flags, GDIPCONST GpMatrix *matrix); 248 PixelFormat format,
249 typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateMatrix2)(REAL m11, REAL m12, RE AL m21, REAL m22, REAL dx, REAL dy, GpMatrix **matrix); 249 BitmapData* lockedBitmapData);
250 typedef GpStatus (WINGDIPAPI *FuncType_GdipDeleteMatrix)(GpMatrix *matrix); 250 typedef GpStatus(WINGDIPAPI* FuncType_GdipGetImagePalette)(
251 typedef GpStatus (WINGDIPAPI *FuncType_GdipSetWorldTransform)(GpGraphics *graphi cs, GpMatrix *matrix); 251 GpImage* image,
252 typedef GpStatus (WINGDIPAPI *FuncType_GdipResetWorldTransform)(GpGraphics *grap hics); 252 ColorPalette* palette,
253 typedef GpStatus (WINGDIPAPI *FuncType_GdipDeleteFontFamily)(GpFontFamily *FontF amily); 253 INT size);
254 typedef GpStatus (WINGDIPAPI *FuncType_GdipDeleteFont)(GpFont* font); 254 typedef GpStatus(WINGDIPAPI* FuncType_GdipGetImagePaletteSize)(GpImage* image,
255 typedef GpStatus (WINGDIPAPI *FuncType_GdipNewPrivateFontCollection)(GpFontColle ction** fontCollection); 255 INT* size);
256 typedef GpStatus (WINGDIPAPI *FuncType_GdipDeletePrivateFontCollection)(GpFontCo llection** fontCollection); 256 typedef GpStatus(WINGDIPAPI* FuncType_GdipBitmapUnlockBits)(
257 typedef GpStatus (WINGDIPAPI *FuncType_GdipPrivateAddMemoryFont)(GpFontCollectio n* fontCollection, GDIPCONST void* memory, INT length); 257 GpBitmap* bitmap,
258 typedef GpStatus (WINGDIPAPI *FuncType_GdipGetFontCollectionFamilyList)(GpFontCo llection* fontCollection, INT numSought, GpFontFamily* gpfamilies[], INT* numFou nd); 258 BitmapData* lockedBitmapData);
259 typedef GpStatus (WINGDIPAPI *FuncType_GdipGetFontCollectionFamilyCount)(GpFontC ollection* fontCollection, INT* numFound); 259 typedef GpStatus(WINGDIPAPI* FuncType_GdipDisposeImage)(GpImage* image);
260 typedef GpStatus (WINGDIPAPI *FuncType_GdipSetTextContrast)(GpGraphics *graphics , UINT contrast); 260 typedef GpStatus(WINGDIPAPI* FuncType_GdipFillRectangle)(GpGraphics* graphics,
261 typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPixelOffsetMode)(GpGraphics* graph ics, PixelOffsetMode pixelOffsetMode); 261 GpBrush* brush,
262 typedef GpStatus (WINGDIPAPI *FuncType_GdipGetImageGraphicsContext)(GpImage *ima ge, GpGraphics **graphics); 262 REAL x,
263 typedef GpStatus (WINGDIPAPI *FuncType_GdipDrawImageI)(GpGraphics *graphics, GpI mage *image, INT x, INT y); 263 REAL y,
264 typedef GpStatus (WINGDIPAPI *FuncType_GdipDrawImageRectI)(GpGraphics *graphics, GpImage *image, INT x, INT y, INT width, INT height); 264 REAL width,
265 typedef GpStatus (WINGDIPAPI *FuncType_GdipDrawString)(GpGraphics *graphics, GDI PCONST WCHAR *string, INT length, GDIPCONST GpFont *font, GDIPCONST RectF *layou tRect, GDIPCONST GpStringFormat *stringFormat, GDIPCONST GpBrush *brush); 265 REAL height);
266 typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenTransform)(GpPen *pen, GpMatrix *matrix); 266 typedef GpStatus(WINGDIPAPI* FuncType_GdipCreateBitmapFromScan0)(
267 #define CallFunc(funcname) ((FuncType_##funcname)GdiplusExt.m_Functions[FuncId_# #funcname]) 267 INT width,
268 typedef HANDLE (__stdcall *FuncType_GdiAddFontMemResourceEx)(PVOID pbFont, DWO RD cbFont, PVOID pdv, DWORD *pcFonts); 268 INT height,
269 typedef BOOL (__stdcall *FuncType_GdiRemoveFontMemResourceEx)(HANDLE handle) ; 269 INT stride,
270 void* CGdiplusExt::GdiAddFontMemResourceEx(void *pFontdata, FX_DWORD size, void* pdv, FX_DWORD* num_face) 270 PixelFormat format,
271 { 271 BYTE* scan0,
272 if (m_pGdiAddFontMemResourceEx) { 272 GpBitmap** bitmap);
273 return ((FuncType_GdiAddFontMemResourceEx)m_pGdiAddFontMemResourceEx)((P VOID)pFontdata, (DWORD)size, (PVOID)pdv, (DWORD*)num_face); 273 typedef GpStatus(WINGDIPAPI* FuncType_GdipSetImagePalette)(
274 } 274 GpImage* image,
275 GDIPCONST ColorPalette* palette);
276 typedef GpStatus(WINGDIPAPI* FuncType_GdipSetInterpolationMode)(
277 GpGraphics* graphics,
278 InterpolationMode interpolationMode);
279 typedef GpStatus(WINGDIPAPI* FuncType_GdipDrawImagePointsI)(
280 GpGraphics* graphics,
281 GpImage* image,
282 GDIPCONST GpPoint* dstpoints,
283 INT count);
284 typedef GpStatus(WINGDIPAPI* FuncType_GdipCreateBitmapFromGdiDib)(
285 GDIPCONST BITMAPINFO* gdiBitmapInfo,
286 VOID* gdiBitmapData,
287 GpBitmap** bitmap);
288 typedef Status(WINAPI* FuncType_GdiplusStartup)(
289 OUT uintptr_t* token,
290 const GdiplusStartupInput* input,
291 OUT GdiplusStartupOutput* output);
292 typedef GpStatus(WINGDIPAPI* FuncType_GdipDrawLineI)(GpGraphics* graphics,
293 GpPen* pen,
294 int x1,
295 int y1,
296 int x2,
297 int y2);
298 typedef GpStatus(WINGDIPAPI* FuncType_GdipResetClip)(GpGraphics* graphics);
299 typedef GpStatus(WINGDIPAPI* FuncType_GdipCreatePath)(GpFillMode brushMode,
300 GpPath** path);
301 typedef GpStatus(WINGDIPAPI* FuncType_GdipAddPathPath)(
302 GpPath* path,
303 GDIPCONST GpPath* addingPath,
304 BOOL connect);
305 typedef GpStatus(WINGDIPAPI* FuncType_GdipSetPathFillMode)(GpPath* path,
306 GpFillMode fillmode);
307 typedef GpStatus(WINGDIPAPI* FuncType_GdipSetClipPath)(GpGraphics* graphics,
308 GpPath* path,
309 CombineMode combineMode);
310 typedef GpStatus(WINGDIPAPI* FuncType_GdipGetClip)(GpGraphics* graphics,
311 GpRegion* region);
312 typedef GpStatus(WINGDIPAPI* FuncType_GdipCreateRegion)(GpRegion** region);
313 typedef GpStatus(WINGDIPAPI* FuncType_GdipGetClipBoundsI)(GpGraphics* graphics,
314 GpRect* rect);
315 typedef GpStatus(WINGDIPAPI* FuncType_GdipSetClipRegion)(
316 GpGraphics* graphics,
317 GpRegion* region,
318 CombineMode combineMode);
319 typedef GpStatus(WINGDIPAPI* FuncType_GdipWidenPath)(GpPath* nativePath,
320 GpPen* pen,
321 GpMatrix* matrix,
322 REAL flatness);
323 typedef GpStatus(WINGDIPAPI* FuncType_GdipAddPathLine)(GpPath* path,
324 REAL x1,
325 REAL y1,
326 REAL x2,
327 REAL y2);
328 typedef GpStatus(WINGDIPAPI* FuncType_GdipAddPathRectangle)(GpPath* path,
329 REAL x,
330 REAL y,
331 REAL width,
332 REAL height);
333 typedef GpStatus(WINGDIPAPI* FuncType_GdipDeleteRegion)(GpRegion* region);
334 typedef GpStatus(WINGDIPAPI* FuncType_GdipGetDC)(GpGraphics* graphics,
335 HDC* hdc);
336 typedef GpStatus(WINGDIPAPI* FuncType_GdipReleaseDC)(GpGraphics* graphics,
337 HDC hdc);
338 typedef GpStatus(WINGDIPAPI* FuncType_GdipSetPenLineCap197819)(
339 GpPen* pen,
340 GpLineCap startCap,
341 GpLineCap endCap,
342 GpDashCap dashCap);
343 typedef GpStatus(WINGDIPAPI* FuncType_GdipSetPenDashOffset)(GpPen* pen,
344 REAL offset);
345 typedef GpStatus(WINGDIPAPI* FuncType_GdipResetPath)(GpPath* path);
346 typedef GpStatus(WINGDIPAPI* FuncType_GdipCreateRegionPath)(GpPath* path,
347 GpRegion** region);
348 typedef GpStatus(WINGDIPAPI* FuncType_GdipCreateFont)(
349 GDIPCONST GpFontFamily* fontFamily,
350 REAL emSize,
351 INT style,
352 Unit unit,
353 GpFont** font);
354 typedef GpStatus(WINGDIPAPI* FuncType_GdipGetFontSize)(GpFont* font,
355 REAL* size);
356 typedef GpStatus(WINGDIPAPI* FuncType_GdipCreateFontFamilyFromName)(
357 GDIPCONST WCHAR* name,
358 GpFontCollection* fontCollection,
359 GpFontFamily** FontFamily);
360 typedef GpStatus(WINGDIPAPI* FuncType_GdipSetTextRenderingHint)(
361 GpGraphics* graphics,
362 TextRenderingHint mode);
363 typedef GpStatus(WINGDIPAPI* FuncType_GdipDrawDriverString)(
364 GpGraphics* graphics,
365 GDIPCONST UINT16* text,
366 INT length,
367 GDIPCONST GpFont* font,
368 GDIPCONST GpBrush* brush,
369 GDIPCONST PointF* positions,
370 INT flags,
371 GDIPCONST GpMatrix* matrix);
372 typedef GpStatus(WINGDIPAPI* FuncType_GdipCreateMatrix2)(REAL m11,
373 REAL m12,
374 REAL m21,
375 REAL m22,
376 REAL dx,
377 REAL dy,
378 GpMatrix** matrix);
379 typedef GpStatus(WINGDIPAPI* FuncType_GdipDeleteMatrix)(GpMatrix* matrix);
380 typedef GpStatus(WINGDIPAPI* FuncType_GdipSetWorldTransform)(
381 GpGraphics* graphics,
382 GpMatrix* matrix);
383 typedef GpStatus(WINGDIPAPI* FuncType_GdipResetWorldTransform)(
384 GpGraphics* graphics);
385 typedef GpStatus(WINGDIPAPI* FuncType_GdipDeleteFontFamily)(
386 GpFontFamily* FontFamily);
387 typedef GpStatus(WINGDIPAPI* FuncType_GdipDeleteFont)(GpFont* font);
388 typedef GpStatus(WINGDIPAPI* FuncType_GdipNewPrivateFontCollection)(
389 GpFontCollection** fontCollection);
390 typedef GpStatus(WINGDIPAPI* FuncType_GdipDeletePrivateFontCollection)(
391 GpFontCollection** fontCollection);
392 typedef GpStatus(WINGDIPAPI* FuncType_GdipPrivateAddMemoryFont)(
393 GpFontCollection* fontCollection,
394 GDIPCONST void* memory,
395 INT length);
396 typedef GpStatus(WINGDIPAPI* FuncType_GdipGetFontCollectionFamilyList)(
397 GpFontCollection* fontCollection,
398 INT numSought,
399 GpFontFamily* gpfamilies[],
400 INT* numFound);
401 typedef GpStatus(WINGDIPAPI* FuncType_GdipGetFontCollectionFamilyCount)(
402 GpFontCollection* fontCollection,
403 INT* numFound);
404 typedef GpStatus(WINGDIPAPI* FuncType_GdipSetTextContrast)(GpGraphics* graphics,
405 UINT contrast);
406 typedef GpStatus(WINGDIPAPI* FuncType_GdipSetPixelOffsetMode)(
407 GpGraphics* graphics,
408 PixelOffsetMode pixelOffsetMode);
409 typedef GpStatus(WINGDIPAPI* FuncType_GdipGetImageGraphicsContext)(
410 GpImage* image,
411 GpGraphics** graphics);
412 typedef GpStatus(WINGDIPAPI* FuncType_GdipDrawImageI)(GpGraphics* graphics,
413 GpImage* image,
414 INT x,
415 INT y);
416 typedef GpStatus(WINGDIPAPI* FuncType_GdipDrawImageRectI)(GpGraphics* graphics,
417 GpImage* image,
418 INT x,
419 INT y,
420 INT width,
421 INT height);
422 typedef GpStatus(WINGDIPAPI* FuncType_GdipDrawString)(
423 GpGraphics* graphics,
424 GDIPCONST WCHAR* string,
425 INT length,
426 GDIPCONST GpFont* font,
427 GDIPCONST RectF* layoutRect,
428 GDIPCONST GpStringFormat* stringFormat,
429 GDIPCONST GpBrush* brush);
430 typedef GpStatus(WINGDIPAPI* FuncType_GdipSetPenTransform)(GpPen* pen,
431 GpMatrix* matrix);
432 #define CallFunc(funcname) \
433 ((FuncType_##funcname)GdiplusExt.m_Functions[FuncId_##funcname])
434 typedef HANDLE(__stdcall* FuncType_GdiAddFontMemResourceEx)(PVOID pbFont,
435 DWORD cbFont,
436 PVOID pdv,
437 DWORD* pcFonts);
438 typedef BOOL(__stdcall* FuncType_GdiRemoveFontMemResourceEx)(HANDLE handle);
439 void* CGdiplusExt::GdiAddFontMemResourceEx(void* pFontdata,
440 FX_DWORD size,
441 void* pdv,
442 FX_DWORD* num_face) {
443 if (m_pGdiAddFontMemResourceEx) {
444 return ((FuncType_GdiAddFontMemResourceEx)m_pGdiAddFontMemResourceEx)(
445 (PVOID)pFontdata, (DWORD)size, (PVOID)pdv, (DWORD*)num_face);
446 }
447 return NULL;
448 }
449 FX_BOOL CGdiplusExt::GdiRemoveFontMemResourceEx(void* handle) {
450 if (m_pGdiRemoveFontMemResourseEx) {
451 return ((FuncType_GdiRemoveFontMemResourceEx)m_pGdiRemoveFontMemResourseEx)(
452 (HANDLE)handle);
453 }
454 return FALSE;
455 }
456 static GpBrush* _GdipCreateBrush(DWORD argb) {
457 CGdiplusExt& GdiplusExt =
458 ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
459 GpSolidFill* solidBrush = NULL;
460 CallFunc(GdipCreateSolidFill)((ARGB)argb, &solidBrush);
461 return solidBrush;
462 }
463 static CFX_DIBitmap* _StretchMonoToGray(int dest_width,
464 int dest_height,
465 const CFX_DIBitmap* pSource,
466 FX_RECT* pClipRect) {
467 FX_BOOL bFlipX = dest_width < 0;
468 if (bFlipX) {
469 dest_width = -dest_width;
470 }
471 FX_BOOL bFlipY = dest_height < 0;
472 if (bFlipY) {
473 dest_height = -dest_height;
474 }
475 int result_width = pClipRect->Width();
476 int result_height = pClipRect->Height();
477 int result_pitch = (result_width + 3) / 4 * 4;
478 CFX_DIBitmap* pStretched = new CFX_DIBitmap;
479 if (!pStretched->Create(result_width, result_height, FXDIB_8bppRgb)) {
480 delete pStretched;
275 return NULL; 481 return NULL;
276 } 482 }
277 FX_BOOL CGdiplusExt::GdiRemoveFontMemResourceEx(void* handle) 483 LPBYTE dest_buf = pStretched->GetBuffer();
278 { 484 int src_width = pSource->GetWidth();
279 if (m_pGdiRemoveFontMemResourseEx) { 485 int src_height = pSource->GetHeight();
280 return ((FuncType_GdiRemoveFontMemResourceEx)m_pGdiRemoveFontMemResourse Ex)((HANDLE)handle); 486 int src_count = src_width * src_height;
281 } 487 int dest_count = dest_width * dest_height;
282 return FALSE; 488 int ratio = 255 * dest_count / src_count;
283 } 489 int y_unit = src_height / dest_height;
284 static GpBrush* _GdipCreateBrush(DWORD argb) 490 int x_unit = src_width / dest_width;
285 { 491 int area_unit = y_unit * x_unit;
286 CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatform Data())->m_GdiplusExt; 492 LPBYTE src_buf = pSource->GetBuffer();
287 GpSolidFill* solidBrush = NULL; 493 int src_pitch = pSource->GetPitch();
494 for (int dest_y = 0; dest_y < result_height; dest_y++) {
495 LPBYTE dest_scan = dest_buf + dest_y * result_pitch;
496 int src_y_start = bFlipY ? (dest_height - 1 - dest_y - pClipRect->top)
497 : (dest_y + pClipRect->top);
498 src_y_start = src_y_start * src_height / dest_height;
499 LPBYTE src_scan = src_buf + src_y_start * src_pitch;
500 for (int dest_x = 0; dest_x < result_width; dest_x++) {
501 int sum = 0;
502 int src_x_start = bFlipX ? (dest_width - 1 - dest_x - pClipRect->left)
503 : (dest_x + pClipRect->left);
504 src_x_start = src_x_start * src_width / dest_width;
505 int src_x_end = src_x_start + x_unit;
506 LPBYTE src_line = src_scan;
507 for (int src_y = 0; src_y < y_unit; src_y++) {
508 for (int src_x = src_x_start; src_x < src_x_end; src_x++) {
509 if (!(src_line[src_x / 8] & (1 << (7 - src_x % 8)))) {
510 sum += 255;
511 }
512 }
513 src_line += src_pitch;
514 }
515 dest_scan[dest_x] = 255 - sum / area_unit;
516 }
517 }
518 return pStretched;
519 }
520 static void OutputImageMask(GpGraphics* pGraphics,
521 BOOL bMonoDevice,
522 const CFX_DIBitmap* pBitmap,
523 int dest_left,
524 int dest_top,
525 int dest_width,
526 int dest_height,
527 FX_ARGB argb,
528 const FX_RECT* pClipRect) {
529 ASSERT(pBitmap->GetBPP() == 1);
530 CGdiplusExt& GdiplusExt =
531 ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
532 int src_width = pBitmap->GetWidth(), src_height = pBitmap->GetHeight();
533 int src_pitch = pBitmap->GetPitch();
534 uint8_t* scan0 = pBitmap->GetBuffer();
535 if (src_width == 1 && src_height == 1) {
536 if ((scan0[0] & 0x80) == 0) {
537 return;
538 }
539 GpSolidFill* solidBrush;
288 CallFunc(GdipCreateSolidFill)((ARGB)argb, &solidBrush); 540 CallFunc(GdipCreateSolidFill)((ARGB)argb, &solidBrush);
289 return solidBrush; 541 if (dest_width < 0) {
290 } 542 dest_width = -dest_width;
291 static CFX_DIBitmap* _StretchMonoToGray(int dest_width, int dest_height, 543 dest_left -= dest_width;
292 const CFX_DIBitmap* pSource, FX_RECT* pC lipRect) 544 }
293 { 545 if (dest_height < 0) {
294 FX_BOOL bFlipX = dest_width < 0; 546 dest_height = -dest_height;
295 if (bFlipX) { 547 dest_top -= dest_height;
296 dest_width = -dest_width; 548 }
297 } 549 CallFunc(GdipFillRectangle)(pGraphics, solidBrush, (float)dest_left,
298 FX_BOOL bFlipY = dest_height < 0; 550 (float)dest_top, (float)dest_width,
299 if (bFlipY) { 551 (float)dest_height);
300 dest_height = -dest_height; 552 CallFunc(GdipDeleteBrush)(solidBrush);
301 } 553 return;
302 int result_width = pClipRect->Width(); 554 }
303 int result_height = pClipRect->Height(); 555 if (!bMonoDevice && abs(dest_width) < src_width &&
304 int result_pitch = (result_width + 3) / 4 * 4; 556 abs(dest_height) < src_height) {
305 CFX_DIBitmap* pStretched = new CFX_DIBitmap; 557 FX_RECT image_rect(dest_left, dest_top, dest_left + dest_width,
306 if (!pStretched->Create(result_width, result_height, FXDIB_8bppRgb)) { 558 dest_top + dest_height);
307 delete pStretched; 559 image_rect.Normalize();
308 return NULL; 560 FX_RECT image_clip = image_rect;
309 } 561 image_clip.Intersect(*pClipRect);
310 LPBYTE dest_buf = pStretched->GetBuffer(); 562 if (image_clip.IsEmpty()) {
311 int src_width = pSource->GetWidth(); 563 return;
312 int src_height = pSource->GetHeight(); 564 }
313 int src_count = src_width * src_height; 565 image_clip.Offset(-image_rect.left, -image_rect.top);
314 int dest_count = dest_width * dest_height; 566 CFX_DIBitmap* pStretched = NULL;
315 int ratio = 255 * dest_count / src_count; 567 if (src_width * src_height > 10000) {
316 int y_unit = src_height / dest_height; 568 pStretched =
317 int x_unit = src_width / dest_width; 569 _StretchMonoToGray(dest_width, dest_height, pBitmap, &image_clip);
318 int area_unit = y_unit * x_unit; 570 } else {
319 LPBYTE src_buf = pSource->GetBuffer(); 571 pStretched =
320 int src_pitch = pSource->GetPitch(); 572 pBitmap->StretchTo(dest_width, dest_height, FALSE, &image_clip);
321 for (int dest_y = 0; dest_y < result_height; dest_y ++) { 573 }
322 LPBYTE dest_scan = dest_buf + dest_y * result_pitch; 574 GpBitmap* bitmap;
323 int src_y_start = bFlipY ? (dest_height - 1 - dest_y - pClipRect->top) : (dest_y + pClipRect->top); 575 CallFunc(GdipCreateBitmapFromScan0)(image_clip.Width(), image_clip.Height(),
324 src_y_start = src_y_start * src_height / dest_height; 576 (image_clip.Width() + 3) / 4 * 4,
325 LPBYTE src_scan = src_buf + src_y_start * src_pitch; 577 PixelFormat8bppIndexed,
326 for (int dest_x = 0; dest_x < result_width; dest_x ++) { 578 pStretched->GetBuffer(), &bitmap);
327 int sum = 0; 579 int a, r, g, b;
328 int src_x_start = bFlipX ? (dest_width - 1 - dest_x - pClipRect->lef t) : (dest_x + pClipRect->left); 580 ArgbDecode(argb, a, r, g, b);
329 src_x_start = src_x_start * src_width / dest_width; 581 UINT pal[258];
330 int src_x_end = src_x_start + x_unit; 582 pal[0] = 0;
331 LPBYTE src_line = src_scan; 583 pal[1] = 256;
332 for (int src_y = 0; src_y < y_unit; src_y ++) { 584 for (int i = 0; i < 256; i++) {
333 for (int src_x = src_x_start; src_x < src_x_end; src_x ++) { 585 pal[i + 2] = ArgbEncode(i * a / 255, r, g, b);
334 if (!(src_line[src_x / 8] & (1 << (7 - src_x % 8)))) { 586 }
335 sum += 255; 587 CallFunc(GdipSetImagePalette)(bitmap, (ColorPalette*)pal);
336 } 588 CallFunc(GdipDrawImageI)(pGraphics, bitmap,
337 } 589 image_rect.left + image_clip.left,
338 src_line += src_pitch; 590 image_rect.top + image_clip.top);
339 } 591 CallFunc(GdipDisposeImage)(bitmap);
340 dest_scan[dest_x] = 255 - sum / area_unit; 592 delete pStretched;
593 return;
594 }
595 GpBitmap* bitmap;
596 CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch,
597 PixelFormat1bppIndexed, scan0, &bitmap);
598 UINT palette[4] = {PaletteFlagsHasAlpha, 2, 0, argb};
599 CallFunc(GdipSetImagePalette)(bitmap, (ColorPalette*)palette);
600 Point destinationPoints[] = {Point(dest_left, dest_top),
601 Point(dest_left + dest_width, dest_top),
602 Point(dest_left, dest_top + dest_height)};
603 CallFunc(GdipDrawImagePointsI)(pGraphics, bitmap, destinationPoints, 3);
604 CallFunc(GdipDisposeImage)(bitmap);
605 }
606 static void OutputImage(GpGraphics* pGraphics,
607 const CFX_DIBitmap* pBitmap,
608 const FX_RECT* pSrcRect,
609 int dest_left,
610 int dest_top,
611 int dest_width,
612 int dest_height) {
613 int src_width = pSrcRect->Width(), src_height = pSrcRect->Height();
614 CGdiplusExt& GdiplusExt =
615 ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
616 if (pBitmap->GetBPP() == 1 && (pSrcRect->left % 8)) {
617 FX_RECT new_rect(0, 0, src_width, src_height);
618 CFX_DIBitmap* pCloned = pBitmap->Clone(pSrcRect);
619 if (!pCloned) {
620 return;
621 }
622 OutputImage(pGraphics, pCloned, &new_rect, dest_left, dest_top, dest_width,
623 dest_height);
624 delete pCloned;
625 return;
626 }
627 int src_pitch = pBitmap->GetPitch();
628 uint8_t* scan0 = pBitmap->GetBuffer() + pSrcRect->top * src_pitch +
629 pBitmap->GetBPP() * pSrcRect->left / 8;
630 GpBitmap* bitmap = NULL;
631 switch (pBitmap->GetFormat()) {
632 case FXDIB_Argb:
633 CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch,
634 PixelFormat32bppARGB, scan0, &bitmap);
635 break;
636 case FXDIB_Rgb32:
637 CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch,
638 PixelFormat32bppRGB, scan0, &bitmap);
639 break;
640 case FXDIB_Rgb:
641 CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch,
642 PixelFormat24bppRGB, scan0, &bitmap);
643 break;
644 case FXDIB_8bppRgb: {
645 CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch,
646 PixelFormat8bppIndexed, scan0,
647 &bitmap);
648 UINT pal[258];
649 pal[0] = 0;
650 pal[1] = 256;
651 for (int i = 0; i < 256; i++) {
652 pal[i + 2] = pBitmap->GetPaletteEntry(i);
653 }
654 CallFunc(GdipSetImagePalette)(bitmap, (ColorPalette*)pal);
655 break;
656 }
657 case FXDIB_1bppRgb: {
658 CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch,
659 PixelFormat1bppIndexed, scan0,
660 &bitmap);
661 break;
662 }
663 }
664 if (dest_height < 0) {
665 dest_height--;
666 }
667 if (dest_width < 0) {
668 dest_width--;
669 }
670 Point destinationPoints[] = {Point(dest_left, dest_top),
671 Point(dest_left + dest_width, dest_top),
672 Point(dest_left, dest_top + dest_height)};
673 CallFunc(GdipDrawImagePointsI)(pGraphics, bitmap, destinationPoints, 3);
674 CallFunc(GdipDisposeImage)(bitmap);
675 }
676 CGdiplusExt::CGdiplusExt() {
677 m_hModule = NULL;
678 m_GdiModule = NULL;
679 for (int i = 0; i < sizeof g_GdipFuncNames / sizeof(LPCSTR); i++) {
680 m_Functions[i] = NULL;
681 }
682 m_pGdiAddFontMemResourceEx = NULL;
683 m_pGdiRemoveFontMemResourseEx = NULL;
684 }
685 void CGdiplusExt::Load() {
686 CFX_ByteString strPlusPath = "";
687 FX_CHAR buf[MAX_PATH];
688 GetSystemDirectoryA(buf, MAX_PATH);
689 strPlusPath += buf;
690 strPlusPath += "\\";
691 strPlusPath += "GDIPLUS.DLL";
692 m_hModule = LoadLibraryA(strPlusPath);
693 if (m_hModule == NULL) {
694 return;
695 }
696 for (int i = 0; i < sizeof g_GdipFuncNames / sizeof(LPCSTR); i++) {
697 m_Functions[i] = GetProcAddress(m_hModule, g_GdipFuncNames[i]);
698 if (m_Functions[i] == NULL) {
699 m_hModule = NULL;
700 return;
701 }
702 }
703 uintptr_t gdiplusToken;
704 GdiplusStartupInput gdiplusStartupInput;
705 ((FuncType_GdiplusStartup)m_Functions[FuncId_GdiplusStartup])(
706 &gdiplusToken, &gdiplusStartupInput, NULL);
707 m_GdiModule = LoadLibraryA("GDI32.DLL");
708 if (m_GdiModule == NULL) {
709 return;
710 }
711 m_pGdiAddFontMemResourceEx =
712 GetProcAddress(m_GdiModule, "AddFontMemResourceEx");
713 m_pGdiRemoveFontMemResourseEx =
714 GetProcAddress(m_GdiModule, "RemoveFontMemResourceEx");
715 }
716 CGdiplusExt::~CGdiplusExt() {}
717 LPVOID CGdiplusExt::LoadMemFont(LPBYTE pData, FX_DWORD size) {
718 GpFontCollection* pCollection = NULL;
719 CGdiplusExt& GdiplusExt =
720 ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
721 CallFunc(GdipNewPrivateFontCollection)(&pCollection);
722 GpStatus status =
723 CallFunc(GdipPrivateAddMemoryFont)(pCollection, pData, size);
724 if (status == Ok) {
725 return pCollection;
726 }
727 CallFunc(GdipDeletePrivateFontCollection)(&pCollection);
728 return NULL;
729 }
730 void CGdiplusExt::DeleteMemFont(LPVOID pCollection) {
731 CGdiplusExt& GdiplusExt =
732 ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
733 CallFunc(GdipDeletePrivateFontCollection)((GpFontCollection**)&pCollection);
734 }
735 FX_BOOL CGdiplusExt::GdipCreateBitmap(CFX_DIBitmap* pBitmap, void** bitmap) {
736 CGdiplusExt& GdiplusExt =
737 ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
738 PixelFormat format;
739 switch (pBitmap->GetFormat()) {
740 case FXDIB_Rgb:
741 format = PixelFormat24bppRGB;
742 break;
743 case FXDIB_Rgb32:
744 format = PixelFormat32bppRGB;
745 break;
746 case FXDIB_Argb:
747 format = PixelFormat32bppARGB;
748 break;
749 default:
750 return FALSE;
751 }
752 GpStatus status = CallFunc(GdipCreateBitmapFromScan0)(
753 pBitmap->GetWidth(), pBitmap->GetHeight(), pBitmap->GetPitch(), format,
754 pBitmap->GetBuffer(), (GpBitmap**)bitmap);
755 if (status == Ok) {
756 return TRUE;
757 }
758 return FALSE;
759 }
760 FX_BOOL CGdiplusExt::GdipCreateFromImage(void* bitmap, void** graphics) {
761 CGdiplusExt& GdiplusExt =
762 ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
763 GpStatus status = CallFunc(GdipGetImageGraphicsContext)(
764 (GpBitmap*)bitmap, (GpGraphics**)graphics);
765 if (status == Ok) {
766 return TRUE;
767 }
768 return FALSE;
769 }
770 FX_BOOL CGdiplusExt::GdipCreateFontFamilyFromName(const FX_WCHAR* name,
771 void* pFontCollection,
772 void** pFamily) {
773 CGdiplusExt& GdiplusExt =
774 ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
775 GpStatus status = CallFunc(GdipCreateFontFamilyFromName)(
776 (GDIPCONST WCHAR*)name, (GpFontCollection*)pFontCollection,
777 (GpFontFamily**)pFamily);
778 if (status == Ok) {
779 return TRUE;
780 }
781 return FALSE;
782 }
783 FX_BOOL CGdiplusExt::GdipCreateFontFromFamily(void* pFamily,
784 FX_FLOAT font_size,
785 int fontstyle,
786 int flag,
787 void** pFont) {
788 CGdiplusExt& GdiplusExt =
789 ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
790 GpStatus status =
791 CallFunc(GdipCreateFont)((GpFontFamily*)pFamily, font_size, fontstyle,
792 Unit(flag), (GpFont**)pFont);
793 if (status == Ok) {
794 return TRUE;
795 }
796 return FALSE;
797 }
798 void CGdiplusExt::GdipGetFontSize(void* pFont, FX_FLOAT* size) {
799 REAL get_size;
800 CGdiplusExt& GdiplusExt =
801 ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
802 GpStatus status = CallFunc(GdipGetFontSize)((GpFont*)pFont, (REAL*)&get_size);
803 if (status == Ok) {
804 *size = (FX_FLOAT)get_size;
805 } else {
806 *size = 0;
807 }
808 }
809 void CGdiplusExt::GdipSetTextRenderingHint(void* graphics, int mode) {
810 CGdiplusExt& GdiplusExt =
811 ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
812 CallFunc(GdipSetTextRenderingHint)((GpGraphics*)graphics,
813 (TextRenderingHint)mode);
814 }
815 void CGdiplusExt::GdipSetPageUnit(void* graphics, FX_DWORD unit) {
816 CGdiplusExt& GdiplusExt =
817 ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
818 CallFunc(GdipSetPageUnit)((GpGraphics*)graphics, (GpUnit)unit);
819 }
820 FX_BOOL CGdiplusExt::GdipDrawDriverString(void* graphics,
821 unsigned short* text,
822 int length,
823 void* font,
824 void* brush,
825 void* positions,
826 int flags,
827 const void* matrix) {
828 CGdiplusExt& GdiplusExt =
829 ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
830 GpStatus status = CallFunc(GdipDrawDriverString)(
831 (GpGraphics*)graphics, (GDIPCONST UINT16*)text, (INT)length,
832 (GDIPCONST GpFont*)font, (GDIPCONST GpBrush*)brush,
833 (GDIPCONST PointF*)positions, (INT)flags, (GDIPCONST GpMatrix*)matrix);
834 if (status == Ok) {
835 return TRUE;
836 }
837 return FALSE;
838 }
839 void CGdiplusExt::GdipCreateBrush(FX_DWORD fill_argb, void** pBrush) {
840 CGdiplusExt& GdiplusExt =
841 ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
842 CallFunc(GdipCreateSolidFill)((ARGB)fill_argb, (GpSolidFill**)pBrush);
843 }
844 void CGdiplusExt::GdipDeleteBrush(void* pBrush) {
845 CGdiplusExt& GdiplusExt =
846 ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
847 CallFunc(GdipDeleteBrush)((GpSolidFill*)pBrush);
848 }
849 void* CGdiplusExt::GdipCreateFontFromCollection(void* pFontCollection,
850 FX_FLOAT font_size,
851 int fontstyle) {
852 CGdiplusExt& GdiplusExt =
853 ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
854 int numFamilies = 0;
855 GpStatus status = CallFunc(GdipGetFontCollectionFamilyCount)(
856 (GpFontCollection*)pFontCollection, &numFamilies);
857 if (status != Ok) {
858 return NULL;
859 }
860 GpFontFamily* family_list[1];
861 status = CallFunc(GdipGetFontCollectionFamilyList)(
862 (GpFontCollection*)pFontCollection, 1, family_list, &numFamilies);
863 if (status != Ok) {
864 return NULL;
865 }
866 GpFont* pFont = NULL;
867 status = CallFunc(GdipCreateFont)(family_list[0], font_size, fontstyle,
868 UnitPixel, &pFont);
869 if (status != Ok) {
870 return NULL;
871 }
872 return pFont;
873 }
874 void CGdiplusExt::GdipCreateMatrix(FX_FLOAT a,
875 FX_FLOAT b,
876 FX_FLOAT c,
877 FX_FLOAT d,
878 FX_FLOAT e,
879 FX_FLOAT f,
880 void** matrix) {
881 CGdiplusExt& GdiplusExt =
882 ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
883 CallFunc(GdipCreateMatrix2)(a, b, c, d, e, f, (GpMatrix**)matrix);
884 }
885 void CGdiplusExt::GdipDeleteMatrix(void* matrix) {
886 CGdiplusExt& GdiplusExt =
887 ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
888 CallFunc(GdipDeleteMatrix)((GpMatrix*)matrix);
889 }
890 void CGdiplusExt::GdipDeleteFontFamily(void* pFamily) {
891 CGdiplusExt& GdiplusExt =
892 ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
893 CallFunc(GdipDeleteFontFamily)((GpFontFamily*)pFamily);
894 }
895 void CGdiplusExt::GdipDeleteFont(void* pFont) {
896 CGdiplusExt& GdiplusExt =
897 ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
898 CallFunc(GdipDeleteFont)((GpFont*)pFont);
899 }
900 void CGdiplusExt::GdipSetWorldTransform(void* graphics, void* pMatrix) {
901 CGdiplusExt& GdiplusExt =
902 ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
903 CallFunc(GdipSetWorldTransform)((GpGraphics*)graphics, (GpMatrix*)pMatrix);
904 }
905 void CGdiplusExt::GdipDisposeImage(void* bitmap) {
906 CGdiplusExt& GdiplusExt =
907 ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
908 CallFunc(GdipDisposeImage)((GpBitmap*)bitmap);
909 }
910 void CGdiplusExt::GdipDeleteGraphics(void* graphics) {
911 CGdiplusExt& GdiplusExt =
912 ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
913 CallFunc(GdipDeleteGraphics)((GpGraphics*)graphics);
914 }
915 FX_BOOL CGdiplusExt::StretchBitMask(HDC hDC,
916 BOOL bMonoDevice,
917 const CFX_DIBitmap* pBitmap,
918 int dest_left,
919 int dest_top,
920 int dest_width,
921 int dest_height,
922 FX_DWORD argb,
923 const FX_RECT* pClipRect,
924 int flags) {
925 ASSERT(pBitmap->GetBPP() == 1);
926 CGdiplusExt& GdiplusExt =
927 ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
928 GpGraphics* pGraphics = NULL;
929 CallFunc(GdipCreateFromHDC)(hDC, &pGraphics);
930 CallFunc(GdipSetPageUnit)(pGraphics, UnitPixel);
931 if (flags & FXDIB_NOSMOOTH) {
932 CallFunc(GdipSetInterpolationMode)(pGraphics,
933 InterpolationModeNearestNeighbor);
934 } else {
935 CallFunc(GdipSetInterpolationMode)(pGraphics, InterpolationModeHighQuality);
936 }
937 OutputImageMask(pGraphics, bMonoDevice, pBitmap, dest_left, dest_top,
938 dest_width, dest_height, argb, pClipRect);
939 CallFunc(GdipDeleteGraphics)(pGraphics);
940 return TRUE;
941 }
942 FX_BOOL CGdiplusExt::StretchDIBits(HDC hDC,
943 const CFX_DIBitmap* pBitmap,
944 int dest_left,
945 int dest_top,
946 int dest_width,
947 int dest_height,
948 const FX_RECT* pClipRect,
949 int flags) {
950 GpGraphics* pGraphics;
951 CGdiplusExt& GdiplusExt =
952 ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
953 CallFunc(GdipCreateFromHDC)(hDC, &pGraphics);
954 CallFunc(GdipSetPageUnit)(pGraphics, UnitPixel);
955 if (flags & FXDIB_NOSMOOTH) {
956 CallFunc(GdipSetInterpolationMode)(pGraphics,
957 InterpolationModeNearestNeighbor);
958 } else if (pBitmap->GetWidth() > abs(dest_width) / 2 ||
959 pBitmap->GetHeight() > abs(dest_height) / 2) {
960 CallFunc(GdipSetInterpolationMode)(pGraphics, InterpolationModeHighQuality);
961 } else {
962 CallFunc(GdipSetInterpolationMode)(pGraphics, InterpolationModeBilinear);
963 }
964 FX_RECT src_rect(0, 0, pBitmap->GetWidth(), pBitmap->GetHeight());
965 OutputImage(pGraphics, pBitmap, &src_rect, dest_left, dest_top, dest_width,
966 dest_height);
967 CallFunc(GdipDeleteGraphics)(pGraphics);
968 CallFunc(GdipDeleteGraphics)(pGraphics);
969 return TRUE;
970 }
971 static GpPen* _GdipCreatePen(const CFX_GraphStateData* pGraphState,
972 const CFX_AffineMatrix* pMatrix,
973 DWORD argb,
974 FX_BOOL bTextMode = FALSE) {
975 CGdiplusExt& GdiplusExt =
976 ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
977 FX_FLOAT width = pGraphState ? pGraphState->m_LineWidth : 1.0f;
978 if (!bTextMode) {
979 FX_FLOAT unit =
980 pMatrix == NULL
981 ? 1.0f
982 : FXSYS_Div(1.0f, (pMatrix->GetXUnit() + pMatrix->GetYUnit()) / 2);
983 if (width < unit) {
984 width = unit;
985 }
986 }
987 GpPen* pPen = NULL;
988 CallFunc(GdipCreatePen1)((ARGB)argb, width, UnitWorld, &pPen);
989 LineCap lineCap;
990 DashCap dashCap = DashCapFlat;
991 FX_BOOL bDashExtend = FALSE;
992 switch (pGraphState->m_LineCap) {
993 case CFX_GraphStateData::LineCapButt:
994 lineCap = LineCapFlat;
995 break;
996 case CFX_GraphStateData::LineCapRound:
997 lineCap = LineCapRound;
998 dashCap = DashCapRound;
999 bDashExtend = TRUE;
1000 break;
1001 case CFX_GraphStateData::LineCapSquare:
1002 lineCap = LineCapSquare;
1003 bDashExtend = TRUE;
1004 break;
1005 }
1006 CallFunc(GdipSetPenLineCap197819)(pPen, lineCap, lineCap, dashCap);
1007 LineJoin lineJoin;
1008 switch (pGraphState->m_LineJoin) {
1009 case CFX_GraphStateData::LineJoinMiter:
1010 lineJoin = LineJoinMiterClipped;
1011 break;
1012 case CFX_GraphStateData::LineJoinRound:
1013 lineJoin = LineJoinRound;
1014 break;
1015 case CFX_GraphStateData::LineJoinBevel:
1016 lineJoin = LineJoinBevel;
1017 break;
1018 }
1019 CallFunc(GdipSetPenLineJoin)(pPen, lineJoin);
1020 if (pGraphState->m_DashCount) {
1021 FX_FLOAT* pDashArray = FX_Alloc(
1022 FX_FLOAT, pGraphState->m_DashCount + pGraphState->m_DashCount % 2);
1023 int nCount = 0;
1024 FX_FLOAT on_leftover = 0, off_leftover = 0;
1025 for (int i = 0; i < pGraphState->m_DashCount; i += 2) {
1026 FX_FLOAT on_phase = pGraphState->m_DashArray[i];
1027 FX_FLOAT off_phase;
1028 if (i == pGraphState->m_DashCount - 1) {
1029 off_phase = on_phase;
1030 } else {
1031 off_phase = pGraphState->m_DashArray[i + 1];
1032 }
1033 on_phase /= width;
1034 off_phase /= width;
1035 if (on_phase + off_phase <= 0.00002f) {
1036 on_phase = 1.0f / 10;
1037 off_phase = 1.0f / 10;
1038 }
1039 if (bDashExtend) {
1040 if (off_phase < 1) {
1041 off_phase = 0;
1042 } else {
1043 off_phase -= 1;
341 } 1044 }
342 } 1045 on_phase += 1;
343 return pStretched; 1046 }
344 } 1047 if (on_phase == 0 || off_phase == 0) {
345 static void OutputImageMask(GpGraphics* pGraphics, BOOL bMonoDevice, const CFX_D IBitmap* pBitmap, int dest_left, int dest_top, 1048 if (nCount == 0) {
346 int dest_width, int dest_height, FX_ARGB argb, const FX_RECT* pClipRect) 1049 on_leftover += on_phase;
347 { 1050 off_leftover += off_phase;
348 ASSERT(pBitmap->GetBPP() == 1); 1051 } else {
349 CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatform Data())->m_GdiplusExt; 1052 pDashArray[nCount - 2] += on_phase;
350 int src_width = pBitmap->GetWidth(), src_height = pBitmap->GetHeight(); 1053 pDashArray[nCount - 1] += off_phase;
351 int src_pitch = pBitmap->GetPitch();
352 uint8_t* scan0 = pBitmap->GetBuffer();
353 if (src_width == 1 && src_height == 1) {
354 if ((scan0[0] & 0x80) == 0) {
355 return;
356 } 1054 }
357 GpSolidFill* solidBrush; 1055 } else {
358 CallFunc(GdipCreateSolidFill)((ARGB)argb, &solidBrush); 1056 pDashArray[nCount++] = on_phase + on_leftover;
359 if (dest_width < 0) { 1057 on_leftover = 0;
360 dest_width = -dest_width; 1058 pDashArray[nCount++] = off_phase + off_leftover;
361 dest_left -= dest_width; 1059 off_leftover = 0;
362 } 1060 }
363 if (dest_height < 0) { 1061 }
364 dest_height = -dest_height; 1062 CallFunc(GdipSetPenDashArray)(pPen, pDashArray, nCount);
365 dest_top -= dest_height; 1063 FX_FLOAT phase = pGraphState->m_DashPhase;
366 } 1064 if (bDashExtend) {
367 CallFunc(GdipFillRectangle)(pGraphics, solidBrush, (float)dest_left, (fl oat)dest_top, 1065 if (phase < 0.5f) {
368 (float)dest_width, (float)dest_height); 1066 phase = 0;
369 CallFunc(GdipDeleteBrush)(solidBrush); 1067 } else {
370 return; 1068 phase -= 0.5f;
371 } 1069 }
372 if (!bMonoDevice && abs(dest_width) < src_width && abs(dest_height) < src_he ight) { 1070 }
373 FX_RECT image_rect(dest_left, dest_top, dest_left + dest_width, dest_top + dest_height); 1071 CallFunc(GdipSetPenDashOffset)(pPen, phase);
374 image_rect.Normalize(); 1072 FX_Free(pDashArray);
375 FX_RECT image_clip = image_rect; 1073 pDashArray = NULL;
376 image_clip.Intersect(*pClipRect); 1074 }
377 if (image_clip.IsEmpty()) { 1075 CallFunc(GdipSetPenMiterLimit)(pPen, pGraphState->m_MiterLimit);
378 return; 1076 return pPen;
379 } 1077 }
380 image_clip.Offset(-image_rect.left, -image_rect.top); 1078 static FX_BOOL IsSmallTriangle(PointF* points,
381 CFX_DIBitmap* pStretched = NULL; 1079 const CFX_AffineMatrix* pMatrix,
382 if (src_width * src_height > 10000) { 1080 int& v1,
383 pStretched = _StretchMonoToGray(dest_width, dest_height, pBitmap, &i mage_clip); 1081 int& v2) {
384 } else { 1082 int pairs[] = {1, 2, 0, 2, 0, 1};
385 pStretched = pBitmap->StretchTo(dest_width, dest_height, FALSE, &ima ge_clip); 1083 for (int i = 0; i < 3; i++) {
386 } 1084 int pair1 = pairs[i * 2];
387 GpBitmap* bitmap; 1085 int pair2 = pairs[i * 2 + 1];
388 CallFunc(GdipCreateBitmapFromScan0)(image_clip.Width(), image_clip.Heigh t(), 1086 FX_FLOAT x1 = points[pair1].X, x2 = points[pair2].X;
389 (image_clip.Width() + 3) / 4 * 4, Pi xelFormat8bppIndexed, pStretched->GetBuffer(), &bitmap); 1087 FX_FLOAT y1 = points[pair1].Y, y2 = points[pair2].Y;
390 int a, r, g, b; 1088 if (pMatrix) {
391 ArgbDecode(argb, a, r, g, b); 1089 pMatrix->Transform(x1, y1);
392 UINT pal[258]; 1090 pMatrix->Transform(x2, y2);
393 pal[0] = 0; 1091 }
394 pal[1] = 256; 1092 FX_FLOAT dx = x1 - x2;
395 for (int i = 0; i < 256; i ++) { 1093 FX_FLOAT dy = y1 - y2;
396 pal[i + 2] = ArgbEncode(i * a / 255, r, g, b); 1094 FX_FLOAT distance_square = FXSYS_Mul(dx, dx) + FXSYS_Mul(dy, dy);
397 } 1095 if (distance_square < (1.0f * 2 + 1.0f / 4)) {
398 CallFunc(GdipSetImagePalette)(bitmap, (ColorPalette*)pal); 1096 v1 = i;
399 CallFunc(GdipDrawImageI)(pGraphics, bitmap, image_rect.left + image_clip .left, 1097 v2 = pair1;
400 image_rect.top + image_clip.top); 1098 return TRUE;
401 CallFunc(GdipDisposeImage)(bitmap); 1099 }
402 delete pStretched; 1100 }
403 return; 1101 return FALSE;
404 } 1102 }
405 GpBitmap* bitmap; 1103 FX_BOOL CGdiplusExt::DrawPath(HDC hDC,
406 CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch, PixelF ormat1bppIndexed, scan0, &bitmap); 1104 const CFX_PathData* pPathData,
407 UINT palette[4] = { PaletteFlagsHasAlpha, 2, 0, argb }; 1105 const CFX_AffineMatrix* pObject2Device,
408 CallFunc(GdipSetImagePalette)(bitmap, (ColorPalette*)palette); 1106 const CFX_GraphStateData* pGraphState,
409 Point destinationPoints[] = { 1107 FX_DWORD fill_argb,
410 Point(dest_left, dest_top), 1108 FX_DWORD stroke_argb,
411 Point(dest_left + dest_width, dest_top), 1109 int fill_mode) {
412 Point(dest_left, dest_top + dest_height) 1110 int nPoints = pPathData->GetPointCount();
413 }; 1111 if (nPoints == 0) {
414 CallFunc(GdipDrawImagePointsI)(pGraphics, bitmap, destinationPoints, 3); 1112 return TRUE;
415 CallFunc(GdipDisposeImage)(bitmap); 1113 }
416 } 1114 FX_PATHPOINT* pPoints = pPathData->GetPoints();
417 static void OutputImage(GpGraphics* pGraphics, const CFX_DIBitmap* pBitmap, cons t FX_RECT* pSrcRect, 1115 GpGraphics* pGraphics = NULL;
418 int dest_left, int dest_top, int dest_width, int dest_he ight) 1116 CGdiplusExt& GdiplusExt =
419 { 1117 ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
420 int src_width = pSrcRect->Width(), src_height = pSrcRect->Height(); 1118 CallFunc(GdipCreateFromHDC)(hDC, &pGraphics);
421 CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatform Data())->m_GdiplusExt; 1119 CallFunc(GdipSetPageUnit)(pGraphics, UnitPixel);
422 if (pBitmap->GetBPP() == 1 && (pSrcRect->left % 8)) { 1120 CallFunc(GdipSetPixelOffsetMode)(pGraphics, PixelOffsetModeHalf);
423 FX_RECT new_rect(0, 0, src_width, src_height); 1121 GpMatrix* pMatrix = NULL;
424 CFX_DIBitmap* pCloned = pBitmap->Clone(pSrcRect); 1122 if (pObject2Device) {
425 if (!pCloned) { 1123 CallFunc(GdipCreateMatrix2)(pObject2Device->a, pObject2Device->b,
426 return; 1124 pObject2Device->c, pObject2Device->d,
427 } 1125 pObject2Device->e, pObject2Device->f, &pMatrix);
428 OutputImage(pGraphics, pCloned, &new_rect, dest_left, dest_top, dest_wid th, dest_height); 1126 CallFunc(GdipSetWorldTransform)(pGraphics, pMatrix);
429 delete pCloned; 1127 }
430 return; 1128 PointF* points = FX_Alloc(PointF, nPoints);
431 } 1129 BYTE* types = FX_Alloc(BYTE, nPoints);
432 int src_pitch = pBitmap->GetPitch(); 1130 int nSubPathes = 0;
433 uint8_t* scan0 = pBitmap->GetBuffer() + pSrcRect->top * src_pitch + pBitmap- >GetBPP() * pSrcRect->left / 8; 1131 FX_BOOL bSubClose = FALSE;
434 GpBitmap* bitmap = NULL; 1132 int pos_subclose = 0;
435 switch (pBitmap->GetFormat()) { 1133 FX_BOOL bSmooth = FALSE;
436 case FXDIB_Argb: 1134 int startpoint = 0;
437 CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch , 1135 for (int i = 0; i < nPoints; i++) {
438 PixelFormat32bppARGB, scan0, &bi tmap); 1136 points[i].X = pPoints[i].m_PointX;
439 break; 1137 points[i].Y = pPoints[i].m_PointY;
440 case FXDIB_Rgb32: 1138 FX_FLOAT x, y;
441 CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch , 1139 if (pObject2Device) {
442 PixelFormat32bppRGB, scan0, &bit map); 1140 pObject2Device->Transform(pPoints[i].m_PointX, pPoints[i].m_PointY, x, y);
443 break;
444 case FXDIB_Rgb:
445 CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch ,
446 PixelFormat24bppRGB, scan0, &bit map);
447 break;
448 case FXDIB_8bppRgb: {
449 CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_p itch,
450 PixelFormat8bppIndexed, scan 0, &bitmap);
451 UINT pal[258];
452 pal[0] = 0;
453 pal[1] = 256;
454 for (int i = 0; i < 256; i ++) {
455 pal[i + 2] = pBitmap->GetPaletteEntry(i);
456 }
457 CallFunc(GdipSetImagePalette)(bitmap, (ColorPalette*)pal);
458 break;
459 }
460 case FXDIB_1bppRgb: {
461 CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_p itch,
462 PixelFormat1bppIndexed, scan 0, &bitmap);
463 break;
464 }
465 }
466 if (dest_height < 0) {
467 dest_height --;
468 }
469 if (dest_width < 0) {
470 dest_width --;
471 }
472 Point destinationPoints[] = {
473 Point(dest_left, dest_top),
474 Point(dest_left + dest_width, dest_top),
475 Point(dest_left, dest_top + dest_height)
476 };
477 CallFunc(GdipDrawImagePointsI)(pGraphics, bitmap, destinationPoints, 3);
478 CallFunc(GdipDisposeImage)(bitmap);
479 }
480 CGdiplusExt::CGdiplusExt()
481 {
482 m_hModule = NULL;
483 m_GdiModule = NULL;
484 for (int i = 0; i < sizeof g_GdipFuncNames / sizeof(LPCSTR); i ++) {
485 m_Functions[i] = NULL;
486 }
487 m_pGdiAddFontMemResourceEx = NULL;
488 m_pGdiRemoveFontMemResourseEx = NULL;
489 }
490 void CGdiplusExt::Load()
491 {
492 CFX_ByteString strPlusPath = "";
493 FX_CHAR buf[MAX_PATH];
494 GetSystemDirectoryA(buf, MAX_PATH);
495 strPlusPath += buf;
496 strPlusPath += "\\";
497 strPlusPath += "GDIPLUS.DLL";
498 m_hModule = LoadLibraryA(strPlusPath);
499 if (m_hModule == NULL) {
500 return;
501 }
502 for (int i = 0; i < sizeof g_GdipFuncNames / sizeof(LPCSTR); i ++) {
503 m_Functions[i] = GetProcAddress(m_hModule, g_GdipFuncNames[i]);
504 if (m_Functions[i] == NULL) {
505 m_hModule = NULL;
506 return;
507 }
508 }
509 uintptr_t gdiplusToken;
510 GdiplusStartupInput gdiplusStartupInput;
511 ((FuncType_GdiplusStartup)m_Functions[FuncId_GdiplusStartup])(&gdiplusToken, &gdiplusStartupInput, NULL);
512 m_GdiModule = LoadLibraryA("GDI32.DLL");
513 if (m_GdiModule == NULL) {
514 return;
515 }
516 m_pGdiAddFontMemResourceEx = GetProcAddress(m_GdiModule, "AddFontMemResource Ex");
517 m_pGdiRemoveFontMemResourseEx = GetProcAddress(m_GdiModule, "RemoveFontMemRe sourceEx");
518 }
519 CGdiplusExt::~CGdiplusExt()
520 {
521 }
522 LPVOID CGdiplusExt::LoadMemFont(LPBYTE pData, FX_DWORD size)
523 {
524 GpFontCollection* pCollection = NULL;
525 CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatform Data())->m_GdiplusExt;
526 CallFunc(GdipNewPrivateFontCollection)(&pCollection);
527 GpStatus status = CallFunc(GdipPrivateAddMemoryFont)(pCollection, pData, siz e);
528 if (status == Ok) {
529 return pCollection;
530 }
531 CallFunc(GdipDeletePrivateFontCollection)(&pCollection);
532 return NULL;
533 }
534 void CGdiplusExt::DeleteMemFont(LPVOID pCollection)
535 {
536 CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatform Data())->m_GdiplusExt;
537 CallFunc(GdipDeletePrivateFontCollection)((GpFontCollection**)&pCollection);
538 }
539 FX_BOOL CGdiplusExt::GdipCreateBitmap(CFX_DIBitmap* pBitmap, void**bitmap)
540 {
541 CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatform Data())->m_GdiplusExt;
542 PixelFormat format;
543 switch (pBitmap->GetFormat()) {
544 case FXDIB_Rgb:
545 format = PixelFormat24bppRGB;
546 break;
547 case FXDIB_Rgb32:
548 format = PixelFormat32bppRGB;
549 break;
550 case FXDIB_Argb:
551 format = PixelFormat32bppARGB;
552 break;
553 default:
554 return FALSE;
555 }
556 GpStatus status = CallFunc(GdipCreateBitmapFromScan0)(pBitmap->GetWidth(), p Bitmap->GetHeight(),
557 pBitmap->GetPitch(), format, pBitmap->GetBuffer(), (GpBitm ap**)bitmap);
558 if (status == Ok) {
559 return TRUE;
560 }
561 return FALSE;
562 }
563 FX_BOOL CGdiplusExt::GdipCreateFromImage(void* bitmap, void** graphics)
564 {
565 CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatform Data())->m_GdiplusExt;
566 GpStatus status = CallFunc(GdipGetImageGraphicsContext)((GpBitmap*)bitmap, ( GpGraphics**)graphics);
567 if (status == Ok) {
568 return TRUE;
569 }
570 return FALSE;
571 }
572 FX_BOOL CGdiplusExt::GdipCreateFontFamilyFromName(const FX_WCHAR* name, void* pF ontCollection, void**pFamily)
573 {
574 CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatform Data())->m_GdiplusExt;
575 GpStatus status = CallFunc(GdipCreateFontFamilyFromName)((GDIPCONST WCHAR *) name, (GpFontCollection*)pFontCollection, (GpFontFamily**)pFamily);
576 if (status == Ok) {
577 return TRUE;
578 }
579 return FALSE;
580 }
581 FX_BOOL CGdiplusExt::GdipCreateFontFromFamily(void* pFamily, FX_FLOAT font_size, int fontstyle, int flag, void** pFont)
582 {
583 CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatform Data())->m_GdiplusExt;
584 GpStatus status = CallFunc(GdipCreateFont)((GpFontFamily*)pFamily, font_size , fontstyle, Unit(flag), (GpFont**)pFont);
585 if (status == Ok) {
586 return TRUE;
587 }
588 return FALSE;
589 }
590 void CGdiplusExt::GdipGetFontSize(void *pFont, FX_FLOAT *size)
591 {
592 REAL get_size;
593 CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatform Data())->m_GdiplusExt;
594 GpStatus status = CallFunc(GdipGetFontSize)((GpFont *)pFont, (REAL*)&get_siz e);
595 if (status == Ok) {
596 *size = (FX_FLOAT)get_size;
597 } else { 1141 } else {
598 *size = 0; 1142 x = pPoints[i].m_PointX;
599 } 1143 y = pPoints[i].m_PointY;
600 } 1144 }
601 void CGdiplusExt::GdipSetTextRenderingHint(void* graphics, int mode) 1145 if (x > 50000 * 1.0f) {
602 { 1146 points[i].X = 50000 * 1.0f;
603 CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatform Data())->m_GdiplusExt; 1147 }
604 CallFunc(GdipSetTextRenderingHint)((GpGraphics*)graphics, (TextRenderingHint )mode); 1148 if (x < -50000 * 1.0f) {
605 } 1149 points[i].X = -50000 * 1.0f;
606 void CGdiplusExt::GdipSetPageUnit(void* graphics, FX_DWORD unit) 1150 }
607 { 1151 if (y > 50000 * 1.0f) {
608 CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatform Data())->m_GdiplusExt; 1152 points[i].Y = 50000 * 1.0f;
609 CallFunc(GdipSetPageUnit)((GpGraphics*)graphics, (GpUnit)unit); 1153 }
610 } 1154 if (y < -50000 * 1.0f) {
611 FX_BOOL CGdiplusExt::GdipDrawDriverString(void *graphics, unsigned short *text, int length, 1155 points[i].Y = -50000 * 1.0f;
612 void *font, void* brush, void *positions, int flags, const void *matrix) 1156 }
613 { 1157 int point_type = pPoints[i].m_Flag & FXPT_TYPE;
614 CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatform Data())->m_GdiplusExt; 1158 if (point_type == FXPT_MOVETO) {
615 GpStatus status = CallFunc(GdipDrawDriverString)((GpGraphics*)graphics, (GDI PCONST UINT16 *)text, (INT)length, (GDIPCONST GpFont *)font, (GDIPCONST GpBrush* )brush, 1159 types[i] = PathPointTypeStart;
616 (GDIPCONST PointF *)positions, (INT)flags, (GDIPCONST GpMa trix *)matrix); 1160 nSubPathes++;
617 if (status == Ok) { 1161 bSubClose = FALSE;
618 return TRUE; 1162 startpoint = i;
619 } 1163 } else if (point_type == FXPT_LINETO) {
620 return FALSE; 1164 types[i] = PathPointTypeLine;
621 } 1165 if (pPoints[i - 1].m_Flag == FXPT_MOVETO &&
622 void CGdiplusExt::GdipCreateBrush(FX_DWORD fill_argb, void** pBrush) 1166 (i == nPoints - 1 || pPoints[i + 1].m_Flag == FXPT_MOVETO) &&
623 { 1167 points[i].Y == points[i - 1].Y && points[i].X == points[i - 1].X) {
624 CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatform Data())->m_GdiplusExt; 1168 points[i].X += 0.01f;
625 CallFunc(GdipCreateSolidFill)((ARGB)fill_argb, (GpSolidFill**)pBrush); 1169 continue;
626 } 1170 }
627 void CGdiplusExt::GdipDeleteBrush(void* pBrush) 1171 if (!bSmooth && points[i].X != points[i - 1].X &&
628 { 1172 points[i].Y != points[i - 1].Y) {
629 CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatform Data())->m_GdiplusExt; 1173 bSmooth = TRUE;
630 CallFunc(GdipDeleteBrush)((GpSolidFill*)pBrush); 1174 }
631 } 1175 } else if (point_type == FXPT_BEZIERTO) {
632 void* CGdiplusExt::GdipCreateFontFromCollection(void* pFontCollection, FX_FLOAT font_size, int fontstyle) 1176 types[i] = PathPointTypeBezier;
633 { 1177 bSmooth = TRUE;
634 CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatform Data())->m_GdiplusExt; 1178 }
635 int numFamilies = 0; 1179 if (pPoints[i].m_Flag & FXPT_CLOSEFIGURE) {
636 GpStatus status = CallFunc(GdipGetFontCollectionFamilyCount)((GpFontCollecti on*)pFontCollection, &numFamilies); 1180 if (bSubClose) {
637 if (status != Ok) { 1181 types[pos_subclose] &= ~PathPointTypeCloseSubpath;
638 return NULL; 1182 } else {
639 } 1183 bSubClose = TRUE;
640 GpFontFamily* family_list[1]; 1184 }
641 status = CallFunc(GdipGetFontCollectionFamilyList)((GpFontCollection*)pFontC ollection, 1, family_list, &numFamilies); 1185 pos_subclose = i;
642 if (status != Ok) { 1186 types[i] |= PathPointTypeCloseSubpath;
643 return NULL; 1187 if (!bSmooth && points[i].X != points[startpoint].X &&
644 } 1188 points[i].Y != points[startpoint].Y) {
645 GpFont* pFont = NULL; 1189 bSmooth = TRUE;
646 status = CallFunc(GdipCreateFont)(family_list[0], font_size, fontstyle, Unit Pixel, &pFont); 1190 }
647 if (status != Ok) { 1191 }
648 return NULL; 1192 }
649 } 1193 if (fill_mode & FXFILL_NOPATHSMOOTH) {
650 return pFont; 1194 bSmooth = FALSE;
651 } 1195 CallFunc(GdipSetSmoothingMode)(pGraphics, SmoothingModeNone);
652 void CGdiplusExt::GdipCreateMatrix(FX_FLOAT a, FX_FLOAT b, FX_FLOAT c, FX_FLOAT d, FX_FLOAT e, FX_FLOAT f, void** matrix) 1196 } else if (!(fill_mode & FXFILL_FULLCOVER)) {
653 { 1197 if (!bSmooth && (fill_mode & 3)) {
654 CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatform Data())->m_GdiplusExt; 1198 bSmooth = TRUE;
655 CallFunc(GdipCreateMatrix2)(a, b, c, d, e, f, (GpMatrix**)matrix); 1199 }
656 } 1200 if (bSmooth || (pGraphState && pGraphState->m_LineWidth > 2)) {
657 void CGdiplusExt::GdipDeleteMatrix(void* matrix) 1201 CallFunc(GdipSetSmoothingMode)(pGraphics, SmoothingModeAntiAlias);
658 { 1202 }
659 CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatform Data())->m_GdiplusExt; 1203 }
660 CallFunc(GdipDeleteMatrix)((GpMatrix*)matrix); 1204 int new_fill_mode = fill_mode & 3;
661 } 1205 if (nPoints == 4 && pGraphState == NULL) {
662 void CGdiplusExt::GdipDeleteFontFamily(void* pFamily) 1206 int v1, v2;
663 { 1207 if (IsSmallTriangle(points, pObject2Device, v1, v2)) {
664 CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatform Data())->m_GdiplusExt; 1208 GpPen* pPen = NULL;
665 CallFunc(GdipDeleteFontFamily)((GpFontFamily*)pFamily); 1209 CallFunc(GdipCreatePen1)(fill_argb, 1.0f, UnitPixel, &pPen);
666 } 1210 CallFunc(GdipDrawLineI)(
667 void CGdiplusExt::GdipDeleteFont(void* pFont) 1211 pGraphics, pPen, FXSYS_round(points[v1].X), FXSYS_round(points[v1].Y),
668 { 1212 FXSYS_round(points[v2].X), FXSYS_round(points[v2].Y));
669 CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatform Data())->m_GdiplusExt; 1213 CallFunc(GdipDeletePen)(pPen);
670 CallFunc(GdipDeleteFont)((GpFont*)pFont); 1214 return TRUE;
671 } 1215 }
672 void CGdiplusExt::GdipSetWorldTransform(void* graphics, void* pMatrix) 1216 }
673 { 1217 GpPath* pGpPath = NULL;
674 CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatform Data())->m_GdiplusExt; 1218 CallFunc(GdipCreatePath2)(points, types, nPoints,
675 CallFunc(GdipSetWorldTransform)((GpGraphics*)graphics, (GpMatrix*)pMatrix); 1219 GdiFillType2Gdip(new_fill_mode), &pGpPath);
676 } 1220 if (!pGpPath) {
677 void CGdiplusExt::GdipDisposeImage(void* bitmap)
678 {
679 CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatform Data())->m_GdiplusExt;
680 CallFunc(GdipDisposeImage)((GpBitmap*)bitmap);
681 }
682 void CGdiplusExt::GdipDeleteGraphics(void* graphics)
683 {
684 CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatform Data())->m_GdiplusExt;
685 CallFunc(GdipDeleteGraphics)((GpGraphics*)graphics);
686 }
687 FX_BOOL CGdiplusExt::StretchBitMask(HDC hDC, BOOL bMonoDevice, const CFX_DIBitma p* pBitmap, int dest_left, int dest_top,
688 int dest_width, int dest_height, FX_DWORD ar gb, const FX_RECT* pClipRect, int flags)
689 {
690 ASSERT(pBitmap->GetBPP() == 1);
691 CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatform Data())->m_GdiplusExt;
692 GpGraphics* pGraphics = NULL;
693 CallFunc(GdipCreateFromHDC)(hDC, &pGraphics);
694 CallFunc(GdipSetPageUnit)(pGraphics, UnitPixel);
695 if (flags & FXDIB_NOSMOOTH) {
696 CallFunc(GdipSetInterpolationMode)(pGraphics, InterpolationModeNearestNe ighbor);
697 } else {
698 CallFunc(GdipSetInterpolationMode)(pGraphics, InterpolationModeHighQuali ty);
699 }
700 OutputImageMask(pGraphics, bMonoDevice, pBitmap, dest_left, dest_top, dest_w idth, dest_height, argb, pClipRect);
701 CallFunc(GdipDeleteGraphics)(pGraphics);
702 return TRUE;
703 }
704 FX_BOOL CGdiplusExt::StretchDIBits(HDC hDC, const CFX_DIBitmap* pBitmap, int des t_left, int dest_top,
705 int dest_width, int dest_height, const FX_REC T* pClipRect, int flags)
706 {
707 GpGraphics* pGraphics;
708 CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatform Data())->m_GdiplusExt;
709 CallFunc(GdipCreateFromHDC)(hDC, &pGraphics);
710 CallFunc(GdipSetPageUnit)(pGraphics, UnitPixel);
711 if (flags & FXDIB_NOSMOOTH) {
712 CallFunc(GdipSetInterpolationMode)(pGraphics, InterpolationModeNearestNe ighbor);
713 } else if (pBitmap->GetWidth() > abs(dest_width) / 2 || pBitmap->GetHeight() > abs(dest_height) / 2) {
714 CallFunc(GdipSetInterpolationMode)(pGraphics, InterpolationModeHighQuali ty);
715 } else {
716 CallFunc(GdipSetInterpolationMode)(pGraphics, InterpolationModeBilinear) ;
717 }
718 FX_RECT src_rect(0, 0, pBitmap->GetWidth(), pBitmap->GetHeight());
719 OutputImage(pGraphics, pBitmap, &src_rect, dest_left, dest_top, dest_width, dest_height);
720 CallFunc(GdipDeleteGraphics)(pGraphics);
721 CallFunc(GdipDeleteGraphics)(pGraphics);
722 return TRUE;
723 }
724 static GpPen* _GdipCreatePen(const CFX_GraphStateData* pGraphState, const CFX_Af fineMatrix* pMatrix, DWORD argb, FX_BOOL bTextMode = FALSE)
725 {
726 CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatform Data())->m_GdiplusExt;
727 FX_FLOAT width = pGraphState ? pGraphState->m_LineWidth : 1.0f;
728 if (!bTextMode) {
729 FX_FLOAT unit = pMatrix == NULL ? 1.0f : FXSYS_Div(1.0f, (pMatrix->GetXU nit() + pMatrix->GetYUnit()) / 2);
730 if (width < unit) {
731 width = unit;
732 }
733 }
734 GpPen* pPen = NULL;
735 CallFunc(GdipCreatePen1)((ARGB)argb, width, UnitWorld, &pPen);
736 LineCap lineCap;
737 DashCap dashCap = DashCapFlat;
738 FX_BOOL bDashExtend = FALSE;
739 switch(pGraphState->m_LineCap) {
740 case CFX_GraphStateData::LineCapButt:
741 lineCap = LineCapFlat;
742 break;
743 case CFX_GraphStateData::LineCapRound:
744 lineCap = LineCapRound;
745 dashCap = DashCapRound;
746 bDashExtend = TRUE;
747 break;
748 case CFX_GraphStateData::LineCapSquare:
749 lineCap = LineCapSquare;
750 bDashExtend = TRUE;
751 break;
752 }
753 CallFunc(GdipSetPenLineCap197819)(pPen, lineCap, lineCap, dashCap);
754 LineJoin lineJoin;
755 switch(pGraphState->m_LineJoin) {
756 case CFX_GraphStateData::LineJoinMiter:
757 lineJoin = LineJoinMiterClipped;
758 break;
759 case CFX_GraphStateData::LineJoinRound:
760 lineJoin = LineJoinRound;
761 break;
762 case CFX_GraphStateData::LineJoinBevel:
763 lineJoin = LineJoinBevel;
764 break;
765 }
766 CallFunc(GdipSetPenLineJoin)(pPen, lineJoin);
767 if(pGraphState->m_DashCount) {
768 FX_FLOAT* pDashArray = FX_Alloc(FX_FLOAT, pGraphState->m_DashCount + pGr aphState->m_DashCount % 2);
769 int nCount = 0;
770 FX_FLOAT on_leftover = 0, off_leftover = 0;
771 for (int i = 0; i < pGraphState->m_DashCount; i += 2) {
772 FX_FLOAT on_phase = pGraphState->m_DashArray[i];
773 FX_FLOAT off_phase;
774 if (i == pGraphState->m_DashCount - 1) {
775 off_phase = on_phase;
776 } else {
777 off_phase = pGraphState->m_DashArray[i + 1];
778 }
779 on_phase /= width;
780 off_phase /= width;
781 if (on_phase + off_phase <= 0.00002f) {
782 on_phase = 1.0f / 10;
783 off_phase = 1.0f / 10;
784 }
785 if (bDashExtend) {
786 if (off_phase < 1) {
787 off_phase = 0;
788 } else {
789 off_phase -= 1;
790 }
791 on_phase += 1;
792 }
793 if (on_phase == 0 || off_phase == 0) {
794 if (nCount == 0) {
795 on_leftover += on_phase;
796 off_leftover += off_phase;
797 } else {
798 pDashArray[nCount - 2] += on_phase;
799 pDashArray[nCount - 1] += off_phase;
800 }
801 } else {
802 pDashArray[nCount++] = on_phase + on_leftover;
803 on_leftover = 0;
804 pDashArray[nCount++] = off_phase + off_leftover;
805 off_leftover = 0;
806 }
807 }
808 CallFunc(GdipSetPenDashArray)(pPen, pDashArray, nCount);
809 FX_FLOAT phase = pGraphState->m_DashPhase;
810 if (bDashExtend) {
811 if (phase < 0.5f) {
812 phase = 0;
813 } else {
814 phase -= 0.5f;
815 }
816 }
817 CallFunc(GdipSetPenDashOffset)(pPen, phase);
818 FX_Free(pDashArray);
819 pDashArray = NULL;
820 }
821 CallFunc(GdipSetPenMiterLimit)(pPen, pGraphState->m_MiterLimit);
822 return pPen;
823 }
824 static FX_BOOL IsSmallTriangle(PointF* points, const CFX_AffineMatrix* pMatrix, int& v1, int& v2)
825 {
826 int pairs[] = {1, 2, 0, 2, 0, 1};
827 for (int i = 0; i < 3; i ++) {
828 int pair1 = pairs[i * 2];
829 int pair2 = pairs[i * 2 + 1];
830 FX_FLOAT x1 = points[pair1].X, x2 = points[pair2].X;
831 FX_FLOAT y1 = points[pair1].Y, y2 = points[pair2].Y;
832 if (pMatrix) {
833 pMatrix->Transform(x1, y1);
834 pMatrix->Transform(x2, y2);
835 }
836 FX_FLOAT dx = x1 - x2;
837 FX_FLOAT dy = y1 - y2;
838 FX_FLOAT distance_square = FXSYS_Mul(dx, dx) + FXSYS_Mul(dy, dy);
839 if (distance_square < (1.0f * 2 + 1.0f / 4)) {
840 v1 = i;
841 v2 = pair1;
842 return TRUE;
843 }
844 }
845 return FALSE;
846 }
847 FX_BOOL CGdiplusExt::DrawPath(HDC hDC, const CFX_PathData* pPathData,
848 const CFX_AffineMatrix* pObject2Device,
849 const CFX_GraphStateData* pGraphState,
850 FX_DWORD fill_argb,
851 FX_DWORD stroke_argb,
852 int fill_mode
853 )
854 {
855 int nPoints = pPathData->GetPointCount();
856 if (nPoints == 0) {
857 return TRUE;
858 }
859 FX_PATHPOINT* pPoints = pPathData->GetPoints();
860 GpGraphics* pGraphics = NULL;
861 CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatform Data())->m_GdiplusExt;
862 CallFunc(GdipCreateFromHDC)(hDC, &pGraphics);
863 CallFunc(GdipSetPageUnit)(pGraphics, UnitPixel);
864 CallFunc(GdipSetPixelOffsetMode)(pGraphics, PixelOffsetModeHalf);
865 GpMatrix* pMatrix = NULL;
866 if (pObject2Device) {
867 CallFunc(GdipCreateMatrix2)(pObject2Device->a, pObject2Device->b, pObjec t2Device->c, pObject2Device->d, pObject2Device->e, pObject2Device->f, &pMatrix);
868 CallFunc(GdipSetWorldTransform)(pGraphics, pMatrix);
869 }
870 PointF *points = FX_Alloc(PointF, nPoints);
871 BYTE * types = FX_Alloc(BYTE, nPoints);
872 int nSubPathes = 0;
873 FX_BOOL bSubClose = FALSE;
874 int pos_subclose = 0;
875 FX_BOOL bSmooth = FALSE;
876 int startpoint = 0;
877 for(int i = 0; i < nPoints; i++) {
878 points[i].X = pPoints[i].m_PointX;
879 points[i].Y = pPoints[i].m_PointY;
880 FX_FLOAT x, y;
881 if (pObject2Device) {
882 pObject2Device->Transform(pPoints[i].m_PointX, pPoints[i].m_PointY, x, y);
883 } else {
884 x = pPoints[i].m_PointX;
885 y = pPoints[i].m_PointY;
886 }
887 if (x > 50000 * 1.0f) {
888 points[i].X = 50000 * 1.0f;
889 }
890 if (x < -50000 * 1.0f) {
891 points[i].X = -50000 * 1.0f;
892 }
893 if (y > 50000 * 1.0f) {
894 points[i].Y = 50000 * 1.0f;
895 }
896 if (y < -50000 * 1.0f) {
897 points[i].Y = -50000 * 1.0f;
898 }
899 int point_type = pPoints[i].m_Flag & FXPT_TYPE;
900 if(point_type == FXPT_MOVETO) {
901 types[i] = PathPointTypeStart;
902 nSubPathes ++;
903 bSubClose = FALSE;
904 startpoint = i;
905 } else if (point_type == FXPT_LINETO) {
906 types[i] = PathPointTypeLine;
907 if (pPoints[i - 1].m_Flag == FXPT_MOVETO && (i == nPoints - 1 || pPo ints[i + 1].m_Flag == FXPT_MOVETO) &&
908 points[i].Y == points[i - 1].Y && points[i].X == points[i - 1].X) {
909 points[i].X += 0.01f;
910 continue;
911 }
912 if (!bSmooth && points[i].X != points[i - 1].X && points[i].Y != poi nts[i - 1].Y) {
913 bSmooth = TRUE;
914 }
915 } else if (point_type == FXPT_BEZIERTO) {
916 types[i] = PathPointTypeBezier;
917 bSmooth = TRUE;
918 }
919 if (pPoints[i].m_Flag & FXPT_CLOSEFIGURE) {
920 if (bSubClose) {
921 types[pos_subclose] &= ~PathPointTypeCloseSubpath;
922 } else {
923 bSubClose = TRUE;
924 }
925 pos_subclose = i;
926 types[i] |= PathPointTypeCloseSubpath;
927 if (!bSmooth && points[i].X != points[startpoint].X && points[i].Y ! = points[startpoint].Y) {
928 bSmooth = TRUE;
929 }
930 }
931 }
932 if (fill_mode & FXFILL_NOPATHSMOOTH) {
933 bSmooth = FALSE;
934 CallFunc(GdipSetSmoothingMode)(pGraphics, SmoothingModeNone);
935 } else if (!(fill_mode & FXFILL_FULLCOVER)) {
936 if (!bSmooth && (fill_mode & 3)) {
937 bSmooth = TRUE;
938 }
939 if (bSmooth || (pGraphState && pGraphState->m_LineWidth > 2)) {
940 CallFunc(GdipSetSmoothingMode)(pGraphics, SmoothingModeAntiAlias);
941 }
942 }
943 int new_fill_mode = fill_mode & 3;
944 if (nPoints == 4 && pGraphState == NULL) {
945 int v1, v2;
946 if (IsSmallTriangle(points, pObject2Device, v1, v2)) {
947 GpPen* pPen = NULL;
948 CallFunc(GdipCreatePen1)(fill_argb, 1.0f, UnitPixel, &pPen);
949 CallFunc(GdipDrawLineI)(pGraphics, pPen, FXSYS_round(points[v1].X), FXSYS_round(points[v1].Y),
950 FXSYS_round(points[v2].X), FXSYS_round(point s[v2].Y));
951 CallFunc(GdipDeletePen)(pPen);
952 return TRUE;
953 }
954 }
955 GpPath* pGpPath = NULL;
956 CallFunc(GdipCreatePath2)(points, types, nPoints, GdiFillType2Gdip(new_fill_ mode), &pGpPath);
957 if (!pGpPath) {
958 if (pMatrix) {
959 CallFunc(GdipDeleteMatrix)(pMatrix);
960 }
961 FX_Free(points);
962 FX_Free(types);
963 CallFunc(GdipDeleteGraphics)(pGraphics);
964 return FALSE;
965 }
966 if (new_fill_mode) {
967 GpBrush* pBrush = _GdipCreateBrush(fill_argb);
968 CallFunc(GdipSetPathFillMode)(pGpPath, GdiFillType2Gdip(new_fill_mode));
969 CallFunc(GdipFillPath)(pGraphics, pBrush, pGpPath);
970 CallFunc(GdipDeleteBrush)(pBrush);
971 }
972 if (pGraphState && stroke_argb) {
973 GpPen* pPen = _GdipCreatePen(pGraphState, pObject2Device, stroke_argb, f ill_mode & FX_STROKE_TEXT_MODE);
974 if (nSubPathes == 1) {
975 CallFunc(GdipDrawPath)(pGraphics, pPen, pGpPath);
976 } else {
977 int iStart = 0;
978 for (int i = 0; i < nPoints; i ++) {
979 if (i == nPoints - 1 || types[i + 1] == PathPointTypeStart) {
980 GpPath* pSubPath;
981 CallFunc(GdipCreatePath2)(points + iStart, types + iStart, i - iStart + 1, GdiFillType2Gdip(new_fill_mode), &pSubPath);
982 iStart = i + 1;
983 CallFunc(GdipDrawPath)(pGraphics, pPen, pSubPath);
984 CallFunc(GdipDeletePath)(pSubPath);
985 }
986 }
987 }
988 CallFunc(GdipDeletePen)(pPen);
989 }
990 if (pMatrix) { 1221 if (pMatrix) {
991 CallFunc(GdipDeleteMatrix)(pMatrix); 1222 CallFunc(GdipDeleteMatrix)(pMatrix);
992 } 1223 }
993 FX_Free(points); 1224 FX_Free(points);
994 FX_Free(types); 1225 FX_Free(types);
995 CallFunc(GdipDeletePath)(pGpPath);
996 CallFunc(GdipDeleteGraphics)(pGraphics); 1226 CallFunc(GdipDeleteGraphics)(pGraphics);
997 return TRUE; 1227 return FALSE;
998 } 1228 }
999 class GpStream final : public IStream 1229 if (new_fill_mode) {
1000 { 1230 GpBrush* pBrush = _GdipCreateBrush(fill_argb);
1001 LONG» m_RefCount; 1231 CallFunc(GdipSetPathFillMode)(pGpPath, GdiFillType2Gdip(new_fill_mode));
1002 int m_ReadPos; 1232 CallFunc(GdipFillPath)(pGraphics, pBrush, pGpPath);
1003 CFX_ByteTextBuf» m_InterStream; 1233 CallFunc(GdipDeleteBrush)(pBrush);
1004 public: 1234 }
1005 GpStream() 1235 if (pGraphState && stroke_argb) {
1006 { 1236 GpPen* pPen = _GdipCreatePen(pGraphState, pObject2Device, stroke_argb,
1007 m_RefCount = 1; 1237 fill_mode & FX_STROKE_TEXT_MODE);
1008 m_ReadPos = 0; 1238 if (nSubPathes == 1) {
1009 } 1239 CallFunc(GdipDrawPath)(pGraphics, pPen, pGpPath);
1010 virtual HRESULT STDMETHODCALLTYPE 1240 } else {
1011 QueryInterface(REFIID iid, void ** ppvObject) 1241 int iStart = 0;
1012 { 1242 for (int i = 0; i < nPoints; i++) {
1013 if (iid == __uuidof(IUnknown) || 1243 if (i == nPoints - 1 || types[i + 1] == PathPointTypeStart) {
1014 iid == __uuidof(IStream) || 1244 GpPath* pSubPath;
1015 iid == __uuidof(ISequentialStream))»{ 1245 CallFunc(GdipCreatePath2)(points + iStart, types + iStart,
1016 *ppvObject = static_cast<IStream*>(this); 1246 i - iStart + 1,
1017 AddRef(); 1247 GdiFillType2Gdip(new_fill_mode), &pSubPath);
1018 return S_OK; 1248 iStart = i + 1;
1249 CallFunc(GdipDrawPath)(pGraphics, pPen, pSubPath);
1250 CallFunc(GdipDeletePath)(pSubPath);
1019 } 1251 }
1020 return E_NOINTERFACE; 1252 }
1021 } 1253 }
1022 virtual ULONG STDMETHODCALLTYPE AddRef(void) 1254 CallFunc(GdipDeletePen)(pPen);
1023 { 1255 }
1024 return (ULONG)InterlockedIncrement(&m_RefCount); 1256 if (pMatrix) {
1025 } 1257 CallFunc(GdipDeleteMatrix)(pMatrix);
1026 virtual ULONG STDMETHODCALLTYPE Release(void) 1258 }
1027 { 1259 FX_Free(points);
1028 ULONG res = (ULONG) InterlockedDecrement(&m_RefCount); 1260 FX_Free(types);
1029 if (res == 0) { 1261 CallFunc(GdipDeletePath)(pGpPath);
1030 delete this; 1262 CallFunc(GdipDeleteGraphics)(pGraphics);
1031 } 1263 return TRUE;
1032 return res; 1264 }
1033 } 1265 class GpStream final : public IStream {
1034 public: 1266 LONG m_RefCount;
1035 virtual HRESULT STDMETHODCALLTYPE Read(void* Output, ULONG cb, ULONG* pcbRea d) 1267 int m_ReadPos;
1036 { 1268 CFX_ByteTextBuf m_InterStream;
1037 size_t» bytes_left; 1269
1038 size_t» bytes_out; 1270 public:
1039 if (pcbRead != NULL) { 1271 GpStream() {
1040 *pcbRead = 0; 1272 m_RefCount = 1;
1041 } 1273 m_ReadPos = 0;
1042 if (m_ReadPos == m_InterStream.GetLength()) { 1274 }
1043 return HRESULT_FROM_WIN32(ERROR_END_OF_MEDIA); 1275 virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid,
1044 } 1276 void** ppvObject) {
1045 bytes_left = m_InterStream.GetLength() - m_ReadPos; 1277 if (iid == __uuidof(IUnknown) || iid == __uuidof(IStream) ||
1046 bytes_out = FX_MIN(cb, bytes_left); 1278 iid == __uuidof(ISequentialStream)) {
1047 FXSYS_memcpy(Output, m_InterStream.GetBuffer() + m_ReadPos, bytes_out); 1279 *ppvObject = static_cast<IStream*>(this);
1048 m_ReadPos += (int32_t)bytes_out; 1280 AddRef();
1049 if (pcbRead != NULL) { 1281 return S_OK;
1050 *pcbRead = (ULONG)bytes_out; 1282 }
1051 } 1283 return E_NOINTERFACE;
1052 return S_OK; 1284 }
1053 } 1285 virtual ULONG STDMETHODCALLTYPE AddRef(void) {
1054 virtual HRESULT STDMETHODCALLTYPE Write(void const* Input, ULONG cb, ULONG* pcbWritten) 1286 return (ULONG)InterlockedIncrement(&m_RefCount);
1055 { 1287 }
1056 if (cb <= 0) { 1288 virtual ULONG STDMETHODCALLTYPE Release(void) {
1057 if (pcbWritten != NULL) { 1289 ULONG res = (ULONG)InterlockedDecrement(&m_RefCount);
1058 *pcbWritten = 0; 1290 if (res == 0) {
1059 } 1291 delete this;
1060 return S_OK; 1292 }
1061 } 1293 return res;
1062 m_InterStream.InsertBlock(m_InterStream.GetLength(), Input, cb); 1294 }
1063 if (pcbWritten != NULL) { 1295
1064 *pcbWritten = cb; 1296 public:
1065 } 1297 virtual HRESULT STDMETHODCALLTYPE Read(void* Output,
1066 return S_OK; 1298 ULONG cb,
1067 } 1299 ULONG* pcbRead) {
1068 public: 1300 size_t bytes_left;
1069 virtual HRESULT STDMETHODCALLTYPE SetSize(ULARGE_INTEGER) 1301 size_t bytes_out;
1070 { 1302 if (pcbRead != NULL) {
1071 return E_NOTIMPL; 1303 *pcbRead = 0;
1072 } 1304 }
1073 virtual HRESULT STDMETHODCALLTYPE CopyTo(IStream*, ULARGE_INTEGER, ULARGE_IN TEGER*, ULARGE_INTEGER*) 1305 if (m_ReadPos == m_InterStream.GetLength()) {
1074 { 1306 return HRESULT_FROM_WIN32(ERROR_END_OF_MEDIA);
1075 return E_NOTIMPL; 1307 }
1076 } 1308 bytes_left = m_InterStream.GetLength() - m_ReadPos;
1077 virtual HRESULT STDMETHODCALLTYPE Commit(DWORD) 1309 bytes_out = FX_MIN(cb, bytes_left);
1078 { 1310 FXSYS_memcpy(Output, m_InterStream.GetBuffer() + m_ReadPos, bytes_out);
1079 return E_NOTIMPL; 1311 m_ReadPos += (int32_t)bytes_out;
1080 } 1312 if (pcbRead != NULL) {
1081 virtual HRESULT STDMETHODCALLTYPE Revert(void) 1313 *pcbRead = (ULONG)bytes_out;
1082 { 1314 }
1083 return E_NOTIMPL; 1315 return S_OK;
1084 } 1316 }
1085 virtual HRESULT STDMETHODCALLTYPE LockRegion(ULARGE_INTEGER, ULARGE_INTEGER, DWORD) 1317 virtual HRESULT STDMETHODCALLTYPE Write(void const* Input,
1086 { 1318 ULONG cb,
1087 return E_NOTIMPL; 1319 ULONG* pcbWritten) {
1088 } 1320 if (cb <= 0) {
1089 virtual HRESULT STDMETHODCALLTYPE UnlockRegion(ULARGE_INTEGER, ULARGE_INTEGE R, DWORD) 1321 if (pcbWritten != NULL) {
1090 { 1322 *pcbWritten = 0;
1091 return E_NOTIMPL; 1323 }
1092 } 1324 return S_OK;
1093 virtual HRESULT STDMETHODCALLTYPE Clone(IStream **) 1325 }
1094 { 1326 m_InterStream.InsertBlock(m_InterStream.GetLength(), Input, cb);
1095 return E_NOTIMPL; 1327 if (pcbWritten != NULL) {
1096 } 1328 *pcbWritten = cb;
1097 virtual HRESULT STDMETHODCALLTYPE Seek(LARGE_INTEGER liDistanceToMove, DWORD dwOrigin, ULARGE_INTEGER* lpNewFilePointer) 1329 }
1098 { 1330 return S_OK;
1099 long» start = 0; 1331 }
1100 long» new_read_position; 1332
1101 switch(dwOrigin) { 1333 public:
1102 case STREAM_SEEK_SET: 1334 virtual HRESULT STDMETHODCALLTYPE SetSize(ULARGE_INTEGER) {
1103 start = 0; 1335 return E_NOTIMPL;
1104 break; 1336 }
1105 case STREAM_SEEK_CUR: 1337 virtual HRESULT STDMETHODCALLTYPE CopyTo(IStream*,
1106 start = m_ReadPos; 1338 ULARGE_INTEGER,
1107 break; 1339 ULARGE_INTEGER*,
1108 case STREAM_SEEK_END: 1340 ULARGE_INTEGER*) {
1109 start = m_InterStream.GetLength(); 1341 return E_NOTIMPL;
1110 break; 1342 }
1111 default: 1343 virtual HRESULT STDMETHODCALLTYPE Commit(DWORD) { return E_NOTIMPL; }
1112 return STG_E_INVALIDFUNCTION; 1344 virtual HRESULT STDMETHODCALLTYPE Revert(void) { return E_NOTIMPL; }
1113 break; 1345 virtual HRESULT STDMETHODCALLTYPE LockRegion(ULARGE_INTEGER,
1114 } 1346 ULARGE_INTEGER,
1115 new_read_position = start + (long)liDistanceToMove.QuadPart; 1347 DWORD) {
1116 if (new_read_position < 0 || new_read_position > m_InterStream.GetLength ()) { 1348 return E_NOTIMPL;
1117 return STG_E_SEEKERROR; 1349 }
1118 } 1350 virtual HRESULT STDMETHODCALLTYPE UnlockRegion(ULARGE_INTEGER,
1119 m_ReadPos = new_read_position; 1351 ULARGE_INTEGER,
1120 if (lpNewFilePointer != NULL) { 1352 DWORD) {
1121 lpNewFilePointer->QuadPart = m_ReadPos; 1353 return E_NOTIMPL;
1122 } 1354 }
1123 return S_OK; 1355 virtual HRESULT STDMETHODCALLTYPE Clone(IStream**) { return E_NOTIMPL; }
1124 } 1356 virtual HRESULT STDMETHODCALLTYPE Seek(LARGE_INTEGER liDistanceToMove,
1125 virtual HRESULT STDMETHODCALLTYPE Stat(STATSTG* pStatstg, DWORD grfStatFlag) 1357 DWORD dwOrigin,
1126 { 1358 ULARGE_INTEGER* lpNewFilePointer) {
1127 if (pStatstg == NULL) { 1359 long start = 0;
1128 return STG_E_INVALIDFUNCTION; 1360 long new_read_position;
1129 } 1361 switch (dwOrigin) {
1130 ZeroMemory(pStatstg, sizeof(STATSTG)); 1362 case STREAM_SEEK_SET:
1131 pStatstg->cbSize.QuadPart = m_InterStream.GetLength(); 1363 start = 0;
1132 return S_OK; 1364 break;
1133 } 1365 case STREAM_SEEK_CUR:
1366 start = m_ReadPos;
1367 break;
1368 case STREAM_SEEK_END:
1369 start = m_InterStream.GetLength();
1370 break;
1371 default:
1372 return STG_E_INVALIDFUNCTION;
1373 break;
1374 }
1375 new_read_position = start + (long)liDistanceToMove.QuadPart;
1376 if (new_read_position < 0 ||
1377 new_read_position > m_InterStream.GetLength()) {
1378 return STG_E_SEEKERROR;
1379 }
1380 m_ReadPos = new_read_position;
1381 if (lpNewFilePointer != NULL) {
1382 lpNewFilePointer->QuadPart = m_ReadPos;
1383 }
1384 return S_OK;
1385 }
1386 virtual HRESULT STDMETHODCALLTYPE Stat(STATSTG* pStatstg, DWORD grfStatFlag) {
1387 if (pStatstg == NULL) {
1388 return STG_E_INVALIDFUNCTION;
1389 }
1390 ZeroMemory(pStatstg, sizeof(STATSTG));
1391 pStatstg->cbSize.QuadPart = m_InterStream.GetLength();
1392 return S_OK;
1393 }
1134 }; 1394 };
1135 typedef struct { 1395 typedef struct {
1136 BITMAPINFO*»» pbmi; 1396 BITMAPINFO* pbmi;
1137 int»» » » Stride; 1397 int Stride;
1138 LPBYTE» » » pScan0; 1398 LPBYTE pScan0;
1139 GpBitmap*» » pBitmap; 1399 GpBitmap* pBitmap;
1140 BitmapData*»» pBitmapData; 1400 BitmapData* pBitmapData;
1141 GpStream* pStream; 1401 GpStream* pStream;
1142 } PREVIEW3_DIBITMAP; 1402 } PREVIEW3_DIBITMAP;
1143 static PREVIEW3_DIBITMAP* LoadDIBitmap(WINDIB_Open_Args_ args) 1403 static PREVIEW3_DIBITMAP* LoadDIBitmap(WINDIB_Open_Args_ args) {
1144 { 1404 GpBitmap* pBitmap;
1145 GpBitmap* pBitmap; 1405 GpStream* pStream = NULL;
1146 GpStream* pStream = NULL; 1406 CGdiplusExt& GdiplusExt =
1147 CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatform Data())->m_GdiplusExt; 1407 ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
1148 Status status = Ok; 1408 Status status = Ok;
1149 if (args.flags == WINDIB_OPEN_PATHNAME) { 1409 if (args.flags == WINDIB_OPEN_PATHNAME) {
1150 status = CallFunc(GdipCreateBitmapFromFileICM)((wchar_t*)args.path_name, &pBitmap); 1410 status = CallFunc(GdipCreateBitmapFromFileICM)((wchar_t*)args.path_name,
1151 } else { 1411 &pBitmap);
1152 if (args.memory_size == 0 || !args.memory_base) { 1412 } else {
1153 return NULL; 1413 if (args.memory_size == 0 || !args.memory_base) {
1154 } 1414 return NULL;
1155 pStream = new GpStream; 1415 }
1156 pStream->Write(args.memory_base, (ULONG)args.memory_size, NULL); 1416 pStream = new GpStream;
1157 status = CallFunc(GdipCreateBitmapFromStreamICM)(pStream, &pBitmap); 1417 pStream->Write(args.memory_base, (ULONG)args.memory_size, NULL);
1158 } 1418 status = CallFunc(GdipCreateBitmapFromStreamICM)(pStream, &pBitmap);
1159 if (status != Ok) { 1419 }
1160 if (pStream) { 1420 if (status != Ok) {
1161 pStream->Release(); 1421 if (pStream) {
1162 } 1422 pStream->Release();
1163 return NULL; 1423 }
1164 } 1424 return NULL;
1165 UINT height, width; 1425 }
1166 CallFunc(GdipGetImageHeight)(pBitmap, &height); 1426 UINT height, width;
1167 CallFunc(GdipGetImageWidth)(pBitmap, &width); 1427 CallFunc(GdipGetImageHeight)(pBitmap, &height);
1168 PixelFormat pixel_format; 1428 CallFunc(GdipGetImageWidth)(pBitmap, &width);
1169 CallFunc(GdipGetImagePixelFormat)(pBitmap, &pixel_format); 1429 PixelFormat pixel_format;
1170 int info_size = sizeof(BITMAPINFOHEADER); 1430 CallFunc(GdipGetImagePixelFormat)(pBitmap, &pixel_format);
1171 int bpp = 24; 1431 int info_size = sizeof(BITMAPINFOHEADER);
1172 int dest_pixel_format = PixelFormat24bppRGB; 1432 int bpp = 24;
1173 if (pixel_format == PixelFormat1bppIndexed) { 1433 int dest_pixel_format = PixelFormat24bppRGB;
1174 info_size += 8; 1434 if (pixel_format == PixelFormat1bppIndexed) {
1175 bpp = 1; 1435 info_size += 8;
1176 dest_pixel_format = PixelFormat1bppIndexed; 1436 bpp = 1;
1177 } else if (pixel_format == PixelFormat8bppIndexed) { 1437 dest_pixel_format = PixelFormat1bppIndexed;
1178 info_size += 1024; 1438 } else if (pixel_format == PixelFormat8bppIndexed) {
1179 bpp = 8; 1439 info_size += 1024;
1180 dest_pixel_format = PixelFormat8bppIndexed; 1440 bpp = 8;
1181 } else if (pixel_format == PixelFormat32bppARGB) { 1441 dest_pixel_format = PixelFormat8bppIndexed;
1182 bpp = 32; 1442 } else if (pixel_format == PixelFormat32bppARGB) {
1183 dest_pixel_format = PixelFormat32bppARGB; 1443 bpp = 32;
1184 } 1444 dest_pixel_format = PixelFormat32bppARGB;
1185 LPBYTE buf = FX_Alloc(BYTE, info_size); 1445 }
1186 BITMAPINFOHEADER* pbmih = (BITMAPINFOHEADER*)buf; 1446 LPBYTE buf = FX_Alloc(BYTE, info_size);
1187 pbmih->biBitCount = bpp; 1447 BITMAPINFOHEADER* pbmih = (BITMAPINFOHEADER*)buf;
1188 pbmih->biCompression = BI_RGB; 1448 pbmih->biBitCount = bpp;
1189 pbmih->biHeight = -(int)height; 1449 pbmih->biCompression = BI_RGB;
1190 pbmih->biPlanes = 1; 1450 pbmih->biHeight = -(int)height;
1191 pbmih->biWidth = width; 1451 pbmih->biPlanes = 1;
1192 Rect rect(0, 0, width, height); 1452 pbmih->biWidth = width;
1193 BitmapData* pBitmapData = FX_Alloc(BitmapData, 1); 1453 Rect rect(0, 0, width, height);
1194 CallFunc(GdipBitmapLockBits)(pBitmap, &rect, ImageLockModeRead, 1454 BitmapData* pBitmapData = FX_Alloc(BitmapData, 1);
1195 dest_pixel_format, pBitmapData); 1455 CallFunc(GdipBitmapLockBits)(pBitmap, &rect, ImageLockModeRead,
1196 if (pixel_format == PixelFormat1bppIndexed || pixel_format == PixelFormat8bp pIndexed) { 1456 dest_pixel_format, pBitmapData);
1197 DWORD* ppal = (DWORD*)(buf + sizeof(BITMAPINFOHEADER)); 1457 if (pixel_format == PixelFormat1bppIndexed ||
1198 struct { 1458 pixel_format == PixelFormat8bppIndexed) {
1199 UINT flags; 1459 DWORD* ppal = (DWORD*)(buf + sizeof(BITMAPINFOHEADER));
1200 UINT Count; 1460 struct {
1201 DWORD Entries[256]; 1461 UINT flags;
1202 } pal; 1462 UINT Count;
1203 int size = 0; 1463 DWORD Entries[256];
1204 CallFunc(GdipGetImagePaletteSize)(pBitmap, &size); 1464 } pal;
1205 CallFunc(GdipGetImagePalette)(pBitmap, (ColorPalette*)&pal, size); 1465 int size = 0;
1206 int entries = pixel_format == PixelFormat1bppIndexed ? 2 : 256; 1466 CallFunc(GdipGetImagePaletteSize)(pBitmap, &size);
1207 for (int i = 0; i < entries; i ++) { 1467 CallFunc(GdipGetImagePalette)(pBitmap, (ColorPalette*)&pal, size);
1208 ppal[i] = pal.Entries[i] & 0x00ffffff; 1468 int entries = pixel_format == PixelFormat1bppIndexed ? 2 : 256;
1209 } 1469 for (int i = 0; i < entries; i++) {
1210 } 1470 ppal[i] = pal.Entries[i] & 0x00ffffff;
1211 PREVIEW3_DIBITMAP* pInfo = FX_Alloc(PREVIEW3_DIBITMAP, 1); 1471 }
1212 pInfo->pbmi = (BITMAPINFO*)buf; 1472 }
1213 pInfo->pScan0 = (LPBYTE)pBitmapData->Scan0; 1473 PREVIEW3_DIBITMAP* pInfo = FX_Alloc(PREVIEW3_DIBITMAP, 1);
1214 pInfo->Stride = pBitmapData->Stride; 1474 pInfo->pbmi = (BITMAPINFO*)buf;
1215 pInfo->pBitmap = pBitmap; 1475 pInfo->pScan0 = (LPBYTE)pBitmapData->Scan0;
1216 pInfo->pBitmapData = pBitmapData; 1476 pInfo->Stride = pBitmapData->Stride;
1217 pInfo->pStream = pStream; 1477 pInfo->pBitmap = pBitmap;
1218 return pInfo; 1478 pInfo->pBitmapData = pBitmapData;
1219 } 1479 pInfo->pStream = pStream;
1220 static void FreeDIBitmap(PREVIEW3_DIBITMAP* pInfo) 1480 return pInfo;
1221 { 1481 }
1222 CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatform Data())->m_GdiplusExt; 1482 static void FreeDIBitmap(PREVIEW3_DIBITMAP* pInfo) {
1223 CallFunc(GdipBitmapUnlockBits)(pInfo->pBitmap, pInfo->pBitmapData); 1483 CGdiplusExt& GdiplusExt =
1224 CallFunc(GdipDisposeImage)(pInfo->pBitmap); 1484 ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
1225 FX_Free(pInfo->pBitmapData); 1485 CallFunc(GdipBitmapUnlockBits)(pInfo->pBitmap, pInfo->pBitmapData);
1226 FX_Free((LPBYTE)pInfo->pbmi); 1486 CallFunc(GdipDisposeImage)(pInfo->pBitmap);
1227 if (pInfo->pStream) { 1487 FX_Free(pInfo->pBitmapData);
1228 pInfo->pStream->Release(); 1488 FX_Free((LPBYTE)pInfo->pbmi);
1229 } 1489 if (pInfo->pStream) {
1230 FX_Free(pInfo); 1490 pInfo->pStream->Release();
1231 } 1491 }
1232 CFX_DIBitmap* _FX_WindowsDIB_LoadFromBuf(BITMAPINFO* pbmi, LPVOID pData, FX_BOOL bAlpha); 1492 FX_Free(pInfo);
1233 CFX_DIBitmap* CGdiplusExt::LoadDIBitmap(WINDIB_Open_Args_ args) 1493 }
1234 { 1494 CFX_DIBitmap* _FX_WindowsDIB_LoadFromBuf(BITMAPINFO* pbmi,
1235 PREVIEW3_DIBITMAP* pInfo = ::LoadDIBitmap(args); 1495 LPVOID pData,
1236 if (pInfo == NULL) { 1496 FX_BOOL bAlpha);
1237 return NULL; 1497 CFX_DIBitmap* CGdiplusExt::LoadDIBitmap(WINDIB_Open_Args_ args) {
1238 } 1498 PREVIEW3_DIBITMAP* pInfo = ::LoadDIBitmap(args);
1239 int height = abs(pInfo->pbmi->bmiHeader.biHeight); 1499 if (pInfo == NULL) {
1240 int width = pInfo->pbmi->bmiHeader.biWidth; 1500 return NULL;
1241 int dest_pitch = (width * pInfo->pbmi->bmiHeader.biBitCount + 31) / 32 * 4; 1501 }
1242 LPBYTE pData = FX_Alloc2D(BYTE, dest_pitch, height); 1502 int height = abs(pInfo->pbmi->bmiHeader.biHeight);
1243 if (dest_pitch == pInfo->Stride) { 1503 int width = pInfo->pbmi->bmiHeader.biWidth;
1244 FXSYS_memcpy(pData, pInfo->pScan0, dest_pitch * height); 1504 int dest_pitch = (width * pInfo->pbmi->bmiHeader.biBitCount + 31) / 32 * 4;
1245 } else { 1505 LPBYTE pData = FX_Alloc2D(BYTE, dest_pitch, height);
1246 for (int i = 0; i < height; i ++) { 1506 if (dest_pitch == pInfo->Stride) {
1247 FXSYS_memcpy(pData + dest_pitch * i, pInfo->pScan0 + pInfo->Stride * i, dest_pitch); 1507 FXSYS_memcpy(pData, pInfo->pScan0, dest_pitch * height);
1248 } 1508 } else {
1249 } 1509 for (int i = 0; i < height; i++) {
1250 CFX_DIBitmap* pDIBitmap = _FX_WindowsDIB_LoadFromBuf(pInfo->pbmi, pData, pIn fo->pbmi->bmiHeader.biBitCount == 32); 1510 FXSYS_memcpy(pData + dest_pitch * i, pInfo->pScan0 + pInfo->Stride * i,
1251 FX_Free(pData); 1511 dest_pitch);
1252 FreeDIBitmap(pInfo); 1512 }
1253 return pDIBitmap; 1513 }
1514 CFX_DIBitmap* pDIBitmap = _FX_WindowsDIB_LoadFromBuf(
1515 pInfo->pbmi, pData, pInfo->pbmi->bmiHeader.biBitCount == 32);
1516 FX_Free(pData);
1517 FreeDIBitmap(pInfo);
1518 return pDIBitmap;
1254 } 1519 }
1255 #endif 1520 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698