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

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

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

Powered by Google App Engine
This is Rietveld 408576698