1c2c66affSColin Finck /*
2c2c66affSColin Finck * Copyright (C) 2007 Google (Evan Stade)
3c2c66affSColin Finck *
4c2c66affSColin Finck * This library is free software; you can redistribute it and/or
5c2c66affSColin Finck * modify it under the terms of the GNU Lesser General Public
6c2c66affSColin Finck * License as published by the Free Software Foundation; either
7c2c66affSColin Finck * version 2.1 of the License, or (at your option) any later version.
8c2c66affSColin Finck *
9c2c66affSColin Finck * This library is distributed in the hope that it will be useful,
10c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of
11c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12c2c66affSColin Finck * Lesser General Public License for more details.
13c2c66affSColin Finck *
14c2c66affSColin Finck * You should have received a copy of the GNU Lesser General Public
15c2c66affSColin Finck * License along with this library; if not, write to the Free Software
16c2c66affSColin Finck * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17c2c66affSColin Finck */
18c2c66affSColin Finck
19c2c66affSColin Finck #ifndef __WINE_GP_PRIVATE_H_
20c2c66affSColin Finck #define __WINE_GP_PRIVATE_H_
21c2c66affSColin Finck
22c2c66affSColin Finck #include <math.h>
23c2c66affSColin Finck #include <stdarg.h>
24c2c66affSColin Finck
255f279f2dSAmine Khaldi #include "windef.h"
265f279f2dSAmine Khaldi #include "wingdi.h"
275f279f2dSAmine Khaldi #include "winbase.h"
285f279f2dSAmine Khaldi #include "winuser.h"
29c2c66affSColin Finck
305f279f2dSAmine Khaldi #include "objbase.h"
315f279f2dSAmine Khaldi #include "ocidl.h"
325f279f2dSAmine Khaldi #include "wincodecsdk.h"
335f279f2dSAmine Khaldi #include "wine/heap.h"
345f279f2dSAmine Khaldi #include "wine/list.h"
35c2c66affSColin Finck
365f279f2dSAmine Khaldi #include "gdiplus.h"
37c2c66affSColin Finck
38c2c66affSColin Finck #define GP_DEFAULT_PENSTYLE (PS_GEOMETRIC | PS_SOLID | PS_ENDCAP_FLAT | PS_JOIN_MITER)
39c2c66affSColin Finck #define MAX_ARC_PTS (13)
40c2c66affSColin Finck #define MAX_DASHLEN (16) /* this is a limitation of gdi */
41c2c66affSColin Finck #define INCH_HIMETRIC (2540)
42c2c66affSColin Finck
43c2c66affSColin Finck #define VERSION_MAGIC 0xdbc01001
44c2c66affSColin Finck #define VERSION_MAGIC2 0xdbc01002
45c2c66affSColin Finck #define VALID_MAGIC(x) (((x) & 0xfffff000) == 0xdbc01000)
46c2c66affSColin Finck #define TENSION_CONST (0.3)
47c2c66affSColin Finck
48c2c66affSColin Finck #define GIF_DISPOSE_UNSPECIFIED 0
49c2c66affSColin Finck #define GIF_DISPOSE_DO_NOT_DISPOSE 1
50c2c66affSColin Finck #define GIF_DISPOSE_RESTORE_TO_BKGND 2
51c2c66affSColin Finck #define GIF_DISPOSE_RESTORE_TO_PREV 3
52c2c66affSColin Finck
53c2c66affSColin Finck
54c2c66affSColin Finck COLORREF ARGB2COLORREF(ARGB color) DECLSPEC_HIDDEN;
55c2c66affSColin Finck HBITMAP ARGB2BMP(ARGB color) DECLSPEC_HIDDEN;
56c2c66affSColin Finck extern INT arc2polybezier(GpPointF * points, REAL x1, REAL y1, REAL x2, REAL y2,
57c2c66affSColin Finck REAL startAngle, REAL sweepAngle) DECLSPEC_HIDDEN;
58c2c66affSColin Finck extern REAL gdiplus_atan2(REAL dy, REAL dx) DECLSPEC_HIDDEN;
59c2c66affSColin Finck extern GpStatus hresult_to_status(HRESULT res) DECLSPEC_HIDDEN;
60c2c66affSColin Finck extern REAL units_to_pixels(REAL units, GpUnit unit, REAL dpi) DECLSPEC_HIDDEN;
61c2c66affSColin Finck extern REAL pixels_to_units(REAL pixels, GpUnit unit, REAL dpi) DECLSPEC_HIDDEN;
62c2c66affSColin Finck extern REAL units_scale(GpUnit from, GpUnit to, REAL dpi) DECLSPEC_HIDDEN;
63c2c66affSColin Finck
64c2c66affSColin Finck #define WineCoordinateSpaceGdiDevice ((GpCoordinateSpace)4)
65c2c66affSColin Finck
66c2c66affSColin Finck extern GpStatus gdi_transform_acquire(GpGraphics *graphics);
67c2c66affSColin Finck extern GpStatus gdi_transform_release(GpGraphics *graphics);
68c2c66affSColin Finck extern GpStatus get_graphics_transform(GpGraphics *graphics, GpCoordinateSpace dst_space,
69c2c66affSColin Finck GpCoordinateSpace src_space, GpMatrix *matrix) DECLSPEC_HIDDEN;
70c2c66affSColin Finck extern GpStatus gdip_transform_points(GpGraphics *graphics, GpCoordinateSpace dst_space,
71c2c66affSColin Finck GpCoordinateSpace src_space, GpPointF *points, INT count) DECLSPEC_HIDDEN;
72c2c66affSColin Finck
73c2c66affSColin Finck extern GpStatus graphics_from_image(GpImage *image, GpGraphics **graphics) DECLSPEC_HIDDEN;
74c2c66affSColin Finck extern GpStatus encode_image_png(GpImage *image, IStream* stream, GDIPCONST EncoderParameters* params) DECLSPEC_HIDDEN;
75c2c66affSColin Finck
76c2c66affSColin Finck extern GpStatus METAFILE_GetGraphicsContext(GpMetafile* metafile, GpGraphics **result) DECLSPEC_HIDDEN;
77c2c66affSColin Finck extern GpStatus METAFILE_GetDC(GpMetafile* metafile, HDC *hdc) DECLSPEC_HIDDEN;
78c2c66affSColin Finck extern GpStatus METAFILE_ReleaseDC(GpMetafile* metafile, HDC hdc) DECLSPEC_HIDDEN;
79c2c66affSColin Finck extern GpStatus METAFILE_GraphicsClear(GpMetafile* metafile, ARGB color) DECLSPEC_HIDDEN;
80c2c66affSColin Finck extern GpStatus METAFILE_FillRectangles(GpMetafile* metafile, GpBrush* brush,
81c2c66affSColin Finck GDIPCONST GpRectF* rects, INT count) DECLSPEC_HIDDEN;
82c2c66affSColin Finck extern GpStatus METAFILE_SetClipRect(GpMetafile* metafile,
83c2c66affSColin Finck REAL x, REAL y, REAL width, REAL height, CombineMode mode) DECLSPEC_HIDDEN;
84c2c66affSColin Finck extern GpStatus METAFILE_SetClipRegion(GpMetafile* metafile, GpRegion* region, CombineMode mode) DECLSPEC_HIDDEN;
85c2c66affSColin Finck extern GpStatus METAFILE_SetPageTransform(GpMetafile* metafile, GpUnit unit, REAL scale) DECLSPEC_HIDDEN;
86c2c66affSColin Finck extern GpStatus METAFILE_SetWorldTransform(GpMetafile* metafile, GDIPCONST GpMatrix* transform) DECLSPEC_HIDDEN;
87c2c66affSColin Finck extern GpStatus METAFILE_ScaleWorldTransform(GpMetafile* metafile, REAL sx, REAL sy, MatrixOrder order) DECLSPEC_HIDDEN;
88c2c66affSColin Finck extern GpStatus METAFILE_MultiplyWorldTransform(GpMetafile* metafile, GDIPCONST GpMatrix* matrix, MatrixOrder order) DECLSPEC_HIDDEN;
89c2c66affSColin Finck extern GpStatus METAFILE_RotateWorldTransform(GpMetafile* metafile, REAL angle, MatrixOrder order) DECLSPEC_HIDDEN;
90c2c66affSColin Finck extern GpStatus METAFILE_TranslateWorldTransform(GpMetafile* metafile, REAL dx, REAL dy, MatrixOrder order) DECLSPEC_HIDDEN;
91c2c66affSColin Finck extern GpStatus METAFILE_ResetWorldTransform(GpMetafile* metafile) DECLSPEC_HIDDEN;
92c2c66affSColin Finck extern GpStatus METAFILE_BeginContainer(GpMetafile* metafile, GDIPCONST GpRectF *dstrect,
93c2c66affSColin Finck GDIPCONST GpRectF *srcrect, GpUnit unit, DWORD StackIndex) DECLSPEC_HIDDEN;
94c2c66affSColin Finck extern GpStatus METAFILE_BeginContainerNoParams(GpMetafile* metafile, DWORD StackIndex) DECLSPEC_HIDDEN;
95c2c66affSColin Finck extern GpStatus METAFILE_EndContainer(GpMetafile* metafile, DWORD StackIndex) DECLSPEC_HIDDEN;
96c2c66affSColin Finck extern GpStatus METAFILE_SaveGraphics(GpMetafile* metafile, DWORD StackIndex) DECLSPEC_HIDDEN;
97c2c66affSColin Finck extern GpStatus METAFILE_RestoreGraphics(GpMetafile* metafile, DWORD StackIndex) DECLSPEC_HIDDEN;
98c2c66affSColin Finck extern GpStatus METAFILE_GraphicsDeleted(GpMetafile* metafile) DECLSPEC_HIDDEN;
99c2c66affSColin Finck extern GpStatus METAFILE_DrawImagePointsRect(GpMetafile* metafile, GpImage *image,
100c2c66affSColin Finck GDIPCONST GpPointF *points, INT count, REAL srcx, REAL srcy, REAL srcwidth,
101c2c66affSColin Finck REAL srcheight, GpUnit srcUnit, GDIPCONST GpImageAttributes* imageAttributes,
102c2c66affSColin Finck DrawImageAbort callback, VOID *callbackData) DECLSPEC_HIDDEN;
103c2c66affSColin Finck extern GpStatus METAFILE_AddSimpleProperty(GpMetafile *metafile, SHORT prop, SHORT val) DECLSPEC_HIDDEN;
104c2c66affSColin Finck extern GpStatus METAFILE_DrawPath(GpMetafile *metafile, GpPen *pen, GpPath *path) DECLSPEC_HIDDEN;
105c2c66affSColin Finck extern GpStatus METAFILE_FillPath(GpMetafile *metafile, GpBrush *brush, GpPath *path) DECLSPEC_HIDDEN;
106007122e7SAmine Khaldi extern void METAFILE_Free(GpMetafile *metafile) DECLSPEC_HIDDEN;
107c2c66affSColin Finck
108c2c66affSColin Finck extern void calc_curve_bezier(const GpPointF *pts, REAL tension, REAL *x1,
109c2c66affSColin Finck REAL *y1, REAL *x2, REAL *y2) DECLSPEC_HIDDEN;
110c2c66affSColin Finck extern void calc_curve_bezier_endp(REAL xend, REAL yend, REAL xadj, REAL yadj,
111c2c66affSColin Finck REAL tension, REAL *x, REAL *y) DECLSPEC_HIDDEN;
112c2c66affSColin Finck
113c2c66affSColin Finck extern void free_installed_fonts(void) DECLSPEC_HIDDEN;
114c2c66affSColin Finck
115c2c66affSColin Finck extern BOOL lengthen_path(GpPath *path, INT len) DECLSPEC_HIDDEN;
116c2c66affSColin Finck
117c2c66affSColin Finck extern DWORD write_region_data(const GpRegion *region, void *data) DECLSPEC_HIDDEN;
118c2c66affSColin Finck extern DWORD write_path_data(GpPath *path, void *data) DECLSPEC_HIDDEN;
119c2c66affSColin Finck
120c2c66affSColin Finck extern GpStatus trace_path(GpGraphics *graphics, GpPath *path) DECLSPEC_HIDDEN;
121c2c66affSColin Finck
122c2c66affSColin Finck typedef struct region_element region_element;
123c2c66affSColin Finck extern void delete_element(region_element *element) DECLSPEC_HIDDEN;
124c2c66affSColin Finck
125007122e7SAmine Khaldi extern GpStatus get_hatch_data(GpHatchStyle hatchstyle, const char **result) DECLSPEC_HIDDEN;
126c2c66affSColin Finck
gdip_round(REAL x)127c2c66affSColin Finck static inline INT gdip_round(REAL x)
128c2c66affSColin Finck {
129c2c66affSColin Finck return (INT) floorf(x + 0.5);
130c2c66affSColin Finck }
131c2c66affSColin Finck
ceilr(REAL x)132c2c66affSColin Finck static inline INT ceilr(REAL x)
133c2c66affSColin Finck {
134c2c66affSColin Finck return (INT) ceilf(x);
135c2c66affSColin Finck }
136c2c66affSColin Finck
deg2rad(REAL degrees)137c2c66affSColin Finck static inline REAL deg2rad(REAL degrees)
138c2c66affSColin Finck {
139c2c66affSColin Finck return M_PI * degrees / 180.0;
140c2c66affSColin Finck }
141c2c66affSColin Finck
color_over(ARGB bg,ARGB fg)142c2c66affSColin Finck static inline ARGB color_over(ARGB bg, ARGB fg)
143c2c66affSColin Finck {
144c2c66affSColin Finck BYTE b, g, r, a;
145c2c66affSColin Finck BYTE bg_alpha, fg_alpha;
146c2c66affSColin Finck
147c2c66affSColin Finck fg_alpha = (fg>>24)&0xff;
148c2c66affSColin Finck
149c2c66affSColin Finck if (fg_alpha == 0xff) return fg;
150c2c66affSColin Finck
151c2c66affSColin Finck if (fg_alpha == 0) return bg;
152c2c66affSColin Finck
153c2c66affSColin Finck bg_alpha = (((bg>>24)&0xff) * (0xff-fg_alpha)) / 0xff;
154c2c66affSColin Finck
155c2c66affSColin Finck if (bg_alpha == 0) return fg;
156c2c66affSColin Finck
157c2c66affSColin Finck a = bg_alpha + fg_alpha;
158c2c66affSColin Finck b = ((bg&0xff)*bg_alpha + (fg&0xff)*fg_alpha)/a;
159c2c66affSColin Finck g = (((bg>>8)&0xff)*bg_alpha + ((fg>>8)&0xff)*fg_alpha)/a;
160c2c66affSColin Finck r = (((bg>>16)&0xff)*bg_alpha + ((fg>>16)&0xff)*fg_alpha)/a;
161c2c66affSColin Finck
162c2c66affSColin Finck return (a<<24)|(r<<16)|(g<<8)|b;
163c2c66affSColin Finck }
164c2c66affSColin Finck
165c2c66affSColin Finck /* fg is premult, bg and return value are not */
color_over_fgpremult(ARGB bg,ARGB fg)166c2c66affSColin Finck static inline ARGB color_over_fgpremult(ARGB bg, ARGB fg)
167c2c66affSColin Finck {
168c2c66affSColin Finck BYTE b, g, r, a;
169c2c66affSColin Finck BYTE bg_alpha, fg_alpha;
170c2c66affSColin Finck
171c2c66affSColin Finck fg_alpha = (fg>>24)&0xff;
172c2c66affSColin Finck
173c2c66affSColin Finck if (fg_alpha == 0) return bg;
174c2c66affSColin Finck
175c2c66affSColin Finck bg_alpha = (((bg>>24)&0xff) * (0xff-fg_alpha)) / 0xff;
176c2c66affSColin Finck
177c2c66affSColin Finck a = bg_alpha + fg_alpha;
178c2c66affSColin Finck b = ((bg&0xff)*bg_alpha + (fg&0xff)*0xff)/a;
179c2c66affSColin Finck g = (((bg>>8)&0xff)*bg_alpha + ((fg>>8)&0xff)*0xff)/a;
180c2c66affSColin Finck r = (((bg>>16)&0xff)*bg_alpha + ((fg>>16)&0xff)*0xff)/a;
181c2c66affSColin Finck
182c2c66affSColin Finck return (a<<24)|(r<<16)|(g<<8)|b;
183c2c66affSColin Finck }
184c2c66affSColin Finck
185c2c66affSColin Finck extern const char *debugstr_rectf(const RectF* rc) DECLSPEC_HIDDEN;
186c2c66affSColin Finck
187c2c66affSColin Finck extern const char *debugstr_pointf(const PointF* pt) DECLSPEC_HIDDEN;
188c2c66affSColin Finck
189c2c66affSColin Finck extern void convert_32bppARGB_to_32bppPARGB(UINT width, UINT height,
190c2c66affSColin Finck BYTE *dst_bits, INT dst_stride, const BYTE *src_bits, INT src_stride) DECLSPEC_HIDDEN;
191c2c66affSColin Finck
192c2c66affSColin Finck extern GpStatus convert_pixels(INT width, INT height,
193c2c66affSColin Finck INT dst_stride, BYTE *dst_bits, PixelFormat dst_format,
194c2c66affSColin Finck INT src_stride, const BYTE *src_bits, PixelFormat src_format, ColorPalette *palette) DECLSPEC_HIDDEN;
195c2c66affSColin Finck
196c2c66affSColin Finck extern PixelFormat apply_image_attributes(const GpImageAttributes *attributes, LPBYTE data,
197c2c66affSColin Finck UINT width, UINT height, INT stride, ColorAdjustType type, PixelFormat fmt) DECLSPEC_HIDDEN;
198c2c66affSColin Finck
199c2c66affSColin Finck struct GpMatrix{
200c2c66affSColin Finck REAL matrix[6];
201c2c66affSColin Finck };
202c2c66affSColin Finck
203c2c66affSColin Finck struct GpPen{
204c2c66affSColin Finck UINT style;
205c2c66affSColin Finck GpUnit unit;
206c2c66affSColin Finck REAL width;
207c2c66affSColin Finck GpLineCap endcap;
208c2c66affSColin Finck GpLineCap startcap;
209c2c66affSColin Finck GpDashCap dashcap;
210c2c66affSColin Finck GpCustomLineCap *customstart;
211c2c66affSColin Finck GpCustomLineCap *customend;
212c2c66affSColin Finck GpLineJoin join;
213c2c66affSColin Finck REAL miterlimit;
214c2c66affSColin Finck GpDashStyle dash;
215c2c66affSColin Finck REAL *dashes;
216c2c66affSColin Finck INT numdashes;
217c2c66affSColin Finck REAL offset; /* dash offset */
218c2c66affSColin Finck GpBrush *brush;
219c2c66affSColin Finck GpPenAlignment align;
220c2c66affSColin Finck GpMatrix transform;
221c2c66affSColin Finck };
222c2c66affSColin Finck
223c2c66affSColin Finck struct GpGraphics{
224c2c66affSColin Finck HDC hdc;
225c2c66affSColin Finck HWND hwnd;
226c2c66affSColin Finck BOOL owndc;
227c2c66affSColin Finck BOOL alpha_hdc;
228c2c66affSColin Finck GpImage *image;
229c2c66affSColin Finck ImageType image_type;
230c2c66affSColin Finck SmoothingMode smoothing;
231c2c66affSColin Finck CompositingQuality compqual;
232c2c66affSColin Finck InterpolationMode interpolation;
233c2c66affSColin Finck PixelOffsetMode pixeloffset;
234c2c66affSColin Finck CompositingMode compmode;
235c2c66affSColin Finck TextRenderingHint texthint;
236c2c66affSColin Finck GpUnit unit; /* page unit */
237c2c66affSColin Finck REAL scale; /* page scale */
238c2c66affSColin Finck REAL xres, yres;
239c2c66affSColin Finck GpMatrix worldtrans; /* world transform */
240c2c66affSColin Finck BOOL busy; /* hdc handle obtained by GdipGetDC */
241c2c66affSColin Finck GpRegion *clip; /* in device coords */
242c2c66affSColin Finck UINT textcontrast; /* not used yet. get/set only */
243c2c66affSColin Finck struct list containers;
244c2c66affSColin Finck GraphicsContainer contid; /* last-issued container ID */
245c2c66affSColin Finck INT origin_x, origin_y;
246c2c66affSColin Finck INT gdi_transform_acquire_count, gdi_transform_save;
247c2c66affSColin Finck GpMatrix gdi_transform;
248007122e7SAmine Khaldi HRGN gdi_clip;
249c2c66affSColin Finck /* For giving the caller an HDC when we technically can't: */
250c2c66affSColin Finck HBITMAP temp_hbitmap;
251c2c66affSColin Finck int temp_hbitmap_width;
252c2c66affSColin Finck int temp_hbitmap_height;
253c2c66affSColin Finck BYTE *temp_bits;
254c2c66affSColin Finck HDC temp_hdc;
255c2c66affSColin Finck };
256c2c66affSColin Finck
257c2c66affSColin Finck struct GpBrush{
258c2c66affSColin Finck GpBrushType bt;
259c2c66affSColin Finck };
260c2c66affSColin Finck
261c2c66affSColin Finck struct GpHatch{
262c2c66affSColin Finck GpBrush brush;
263007122e7SAmine Khaldi GpHatchStyle hatchstyle;
264c2c66affSColin Finck ARGB forecol;
265c2c66affSColin Finck ARGB backcol;
266c2c66affSColin Finck };
267c2c66affSColin Finck
268c2c66affSColin Finck struct GpSolidFill{
269c2c66affSColin Finck GpBrush brush;
270c2c66affSColin Finck ARGB color;
271c2c66affSColin Finck };
272c2c66affSColin Finck
273c2c66affSColin Finck struct GpPathGradient{
274c2c66affSColin Finck GpBrush brush;
275c2c66affSColin Finck GpPath* path;
276c2c66affSColin Finck ARGB centercolor;
277c2c66affSColin Finck GpWrapMode wrap;
278c2c66affSColin Finck BOOL gamma;
279c2c66affSColin Finck GpPointF center;
280c2c66affSColin Finck GpPointF focus;
281c2c66affSColin Finck REAL* blendfac; /* blend factors */
282c2c66affSColin Finck REAL* blendpos; /* blend positions */
283c2c66affSColin Finck INT blendcount;
284c2c66affSColin Finck ARGB *surroundcolors;
285c2c66affSColin Finck INT surroundcolorcount;
286c2c66affSColin Finck ARGB* pblendcolor; /* preset blend colors */
287c2c66affSColin Finck REAL* pblendpos; /* preset blend positions */
288c2c66affSColin Finck INT pblendcount;
289c2c66affSColin Finck GpMatrix transform;
290c2c66affSColin Finck };
291c2c66affSColin Finck
292c2c66affSColin Finck struct GpLineGradient{
293c2c66affSColin Finck GpBrush brush;
294c2c66affSColin Finck ARGB startcolor;
295c2c66affSColin Finck ARGB endcolor;
296c2c66affSColin Finck RectF rect;
297c2c66affSColin Finck GpWrapMode wrap;
298c2c66affSColin Finck BOOL gamma;
299c2c66affSColin Finck REAL* blendfac; /* blend factors */
300c2c66affSColin Finck REAL* blendpos; /* blend positions */
301c2c66affSColin Finck INT blendcount;
302c2c66affSColin Finck ARGB* pblendcolor; /* preset blend colors */
303c2c66affSColin Finck REAL* pblendpos; /* preset blend positions */
304c2c66affSColin Finck INT pblendcount;
305c2c66affSColin Finck GpMatrix transform;
306c2c66affSColin Finck };
307c2c66affSColin Finck
308c2c66affSColin Finck struct GpTexture{
309c2c66affSColin Finck GpBrush brush;
310c2c66affSColin Finck GpMatrix transform;
311c2c66affSColin Finck GpImage *image;
312c2c66affSColin Finck GpImageAttributes *imageattributes;
313c2c66affSColin Finck BYTE *bitmap_bits; /* image bits converted to ARGB and run through imageattributes */
314c2c66affSColin Finck };
315c2c66affSColin Finck
316c2c66affSColin Finck struct GpPath{
317c2c66affSColin Finck GpFillMode fill;
318c2c66affSColin Finck GpPathData pathdata;
319c2c66affSColin Finck BOOL newfigure; /* whether the next drawing action starts a new figure */
320c2c66affSColin Finck INT datalen; /* size of the arrays in pathdata */
321c2c66affSColin Finck };
322c2c66affSColin Finck
323c2c66affSColin Finck struct GpPathIterator{
324c2c66affSColin Finck GpPathData pathdata;
325c2c66affSColin Finck INT subpath_pos; /* for NextSubpath methods */
326c2c66affSColin Finck INT marker_pos; /* for NextMarker methods */
327c2c66affSColin Finck INT pathtype_pos; /* for NextPathType methods */
328c2c66affSColin Finck };
329c2c66affSColin Finck
330c2c66affSColin Finck struct GpCustomLineCap{
331c2c66affSColin Finck CustomLineCapType type;
332c2c66affSColin Finck GpPathData pathdata;
333c2c66affSColin Finck BOOL fill; /* TRUE for fill, FALSE for stroke */
334c2c66affSColin Finck GpLineCap cap; /* as far as I can tell, this value is ignored */
335c2c66affSColin Finck REAL inset; /* how much to adjust the end of the line */
336c2c66affSColin Finck GpLineJoin join;
337c2c66affSColin Finck REAL scale;
338c2c66affSColin Finck };
339c2c66affSColin Finck
340c2c66affSColin Finck struct GpAdjustableArrowCap{
341c2c66affSColin Finck GpCustomLineCap cap;
342*6619d026SAmine Khaldi REAL middle_inset;
343*6619d026SAmine Khaldi REAL height;
344*6619d026SAmine Khaldi REAL width;
345c2c66affSColin Finck };
346c2c66affSColin Finck
347c2c66affSColin Finck struct GpImage{
348c2c66affSColin Finck IWICBitmapDecoder *decoder;
349c2c66affSColin Finck ImageType type;
350c2c66affSColin Finck GUID format;
351c2c66affSColin Finck UINT flags;
352c2c66affSColin Finck UINT frame_count, current_frame;
353c2c66affSColin Finck ColorPalette *palette;
354c2c66affSColin Finck REAL xres, yres;
355c2c66affSColin Finck LONG busy;
356c2c66affSColin Finck };
357c2c66affSColin Finck
358007122e7SAmine Khaldi #define EmfPlusObjectTableSize 64
359007122e7SAmine Khaldi
360007122e7SAmine Khaldi typedef enum EmfPlusObjectType
361007122e7SAmine Khaldi {
362007122e7SAmine Khaldi ObjectTypeInvalid,
363007122e7SAmine Khaldi ObjectTypeBrush,
364007122e7SAmine Khaldi ObjectTypePen,
365007122e7SAmine Khaldi ObjectTypePath,
366007122e7SAmine Khaldi ObjectTypeRegion,
367007122e7SAmine Khaldi ObjectTypeImage,
368007122e7SAmine Khaldi ObjectTypeFont,
369007122e7SAmine Khaldi ObjectTypeStringFormat,
370007122e7SAmine Khaldi ObjectTypeImageAttributes,
371007122e7SAmine Khaldi ObjectTypeCustomLineCap,
372007122e7SAmine Khaldi ObjectTypeMax = ObjectTypeCustomLineCap,
373007122e7SAmine Khaldi } EmfPlusObjectType;
374007122e7SAmine Khaldi
375007122e7SAmine Khaldi /* Deserialized EmfPlusObject record. */
376007122e7SAmine Khaldi struct emfplus_object {
377007122e7SAmine Khaldi EmfPlusObjectType type;
378007122e7SAmine Khaldi union {
379007122e7SAmine Khaldi GpBrush *brush;
380007122e7SAmine Khaldi GpPen *pen;
381007122e7SAmine Khaldi GpPath *path;
382007122e7SAmine Khaldi GpRegion *region;
383007122e7SAmine Khaldi GpImage *image;
384007122e7SAmine Khaldi GpFont *font;
385007122e7SAmine Khaldi GpImageAttributes *image_attributes;
386007122e7SAmine Khaldi void *object;
387007122e7SAmine Khaldi } u;
388007122e7SAmine Khaldi };
389007122e7SAmine Khaldi
390c2c66affSColin Finck struct GpMetafile{
391c2c66affSColin Finck GpImage image;
392c2c66affSColin Finck GpRectF bounds;
393c2c66affSColin Finck GpUnit unit;
394c2c66affSColin Finck MetafileType metafile_type;
395c2c66affSColin Finck HENHMETAFILE hemf;
396c2c66affSColin Finck int preserve_hemf; /* if true, hemf belongs to the app and should not be deleted */
397c2c66affSColin Finck
398c2c66affSColin Finck /* recording */
399c2c66affSColin Finck HDC record_dc;
400c2c66affSColin Finck GpGraphics *record_graphics;
401c2c66affSColin Finck BYTE *comment_data;
402c2c66affSColin Finck DWORD comment_data_size;
403c2c66affSColin Finck DWORD comment_data_length;
404c2c66affSColin Finck IStream *record_stream;
405c2c66affSColin Finck BOOL auto_frame; /* If true, determine the frame automatically */
406c2c66affSColin Finck GpPointF auto_frame_min, auto_frame_max;
407c2c66affSColin Finck DWORD next_object_id;
408c2c66affSColin Finck
409c2c66affSColin Finck /* playback */
410c2c66affSColin Finck GpGraphics *playback_graphics;
411c2c66affSColin Finck HDC playback_dc;
412c2c66affSColin Finck GpPointF playback_points[3];
413c2c66affSColin Finck GpRectF src_rect;
414c2c66affSColin Finck HANDLETABLE *handle_table;
415c2c66affSColin Finck int handle_count;
416c2c66affSColin Finck XFORM gdiworldtransform;
417c2c66affSColin Finck GpMatrix *world_transform;
418c2c66affSColin Finck GpUnit page_unit;
419c2c66affSColin Finck REAL page_scale;
420c2c66affSColin Finck GpRegion *base_clip; /* clip region in device space for all metafile output */
421c2c66affSColin Finck GpRegion *clip; /* clip region within the metafile */
422c2c66affSColin Finck struct list containers;
423007122e7SAmine Khaldi struct emfplus_object objtable[EmfPlusObjectTableSize];
424c2c66affSColin Finck };
425c2c66affSColin Finck
426c2c66affSColin Finck struct GpBitmap{
427c2c66affSColin Finck GpImage image;
428c2c66affSColin Finck INT width;
429c2c66affSColin Finck INT height;
430c2c66affSColin Finck PixelFormat format;
431c2c66affSColin Finck ImageLockMode lockmode;
432c2c66affSColin Finck BYTE *bitmapbits; /* pointer to the buffer we passed in BitmapLockBits */
433c2c66affSColin Finck HBITMAP hbitmap;
434c2c66affSColin Finck HDC hdc;
435c2c66affSColin Finck BYTE *bits; /* actual image bits if this is a DIB */
436c2c66affSColin Finck INT stride; /* stride of bits if this is a DIB */
437c2c66affSColin Finck BYTE *own_bits; /* image bits that need to be freed with this object */
438c2c66affSColin Finck INT lockx, locky; /* X and Y coordinates of the rect when a bitmap is locked for writing. */
439c2c66affSColin Finck IWICMetadataReader *metadata_reader; /* NULL if there is no metadata */
440c2c66affSColin Finck UINT prop_count;
441c2c66affSColin Finck PropertyItem *prop_item; /* cached image properties */
442c2c66affSColin Finck };
443c2c66affSColin Finck
444c2c66affSColin Finck struct GpCachedBitmap{
445c2c66affSColin Finck GpImage *image;
446c2c66affSColin Finck };
447c2c66affSColin Finck
448c2c66affSColin Finck struct color_key{
449c2c66affSColin Finck BOOL enabled;
450c2c66affSColin Finck ARGB low;
451c2c66affSColin Finck ARGB high;
452c2c66affSColin Finck };
453c2c66affSColin Finck
454c2c66affSColin Finck struct color_matrix{
455c2c66affSColin Finck BOOL enabled;
456c2c66affSColin Finck ColorMatrixFlags flags;
457c2c66affSColin Finck ColorMatrix colormatrix;
458c2c66affSColin Finck ColorMatrix graymatrix;
459c2c66affSColin Finck };
460c2c66affSColin Finck
461c2c66affSColin Finck struct color_remap_table{
462c2c66affSColin Finck BOOL enabled;
463c2c66affSColin Finck INT mapsize;
464c2c66affSColin Finck ColorMap *colormap;
465c2c66affSColin Finck };
466c2c66affSColin Finck
467007122e7SAmine Khaldi enum imageattr_noop{
468007122e7SAmine Khaldi IMAGEATTR_NOOP_UNDEFINED,
469007122e7SAmine Khaldi IMAGEATTR_NOOP_SET,
470007122e7SAmine Khaldi IMAGEATTR_NOOP_CLEAR,
471007122e7SAmine Khaldi };
472007122e7SAmine Khaldi
473c2c66affSColin Finck struct GpImageAttributes{
474c2c66affSColin Finck WrapMode wrap;
475c2c66affSColin Finck ARGB outside_color;
476c2c66affSColin Finck BOOL clamp;
477c2c66affSColin Finck struct color_key colorkeys[ColorAdjustTypeCount];
478c2c66affSColin Finck struct color_matrix colormatrices[ColorAdjustTypeCount];
479c2c66affSColin Finck struct color_remap_table colorremaptables[ColorAdjustTypeCount];
480c2c66affSColin Finck BOOL gamma_enabled[ColorAdjustTypeCount];
481c2c66affSColin Finck REAL gamma[ColorAdjustTypeCount];
482007122e7SAmine Khaldi enum imageattr_noop noop[ColorAdjustTypeCount];
483c2c66affSColin Finck };
484c2c66affSColin Finck
485c2c66affSColin Finck struct GpFont{
486c2c66affSColin Finck GpFontFamily *family;
487c2c66affSColin Finck OUTLINETEXTMETRICW otm;
488c2c66affSColin Finck REAL emSize; /* in font units */
489c2c66affSColin Finck Unit unit;
490c2c66affSColin Finck };
491c2c66affSColin Finck
492c2c66affSColin Finck extern const struct GpStringFormat default_drawstring_format DECLSPEC_HIDDEN;
493c2c66affSColin Finck
494c2c66affSColin Finck struct GpStringFormat{
495c2c66affSColin Finck INT attr;
496c2c66affSColin Finck LANGID lang;
497c2c66affSColin Finck LANGID digitlang;
498c2c66affSColin Finck StringAlignment align;
499c2c66affSColin Finck StringTrimming trimming;
500c2c66affSColin Finck HotkeyPrefix hkprefix;
501c2c66affSColin Finck StringAlignment line_align;
502c2c66affSColin Finck StringDigitSubstitute digitsub;
503c2c66affSColin Finck INT tabcount;
504c2c66affSColin Finck REAL firsttab;
505c2c66affSColin Finck REAL *tabs;
506c2c66affSColin Finck CharacterRange *character_ranges;
507c2c66affSColin Finck INT range_count;
508c2c66affSColin Finck BOOL generic_typographic;
509c2c66affSColin Finck };
510c2c66affSColin Finck
511c2c66affSColin Finck extern void init_generic_string_formats(void) DECLSPEC_HIDDEN;
512c2c66affSColin Finck extern void free_generic_string_formats(void) DECLSPEC_HIDDEN;
513c2c66affSColin Finck
514c2c66affSColin Finck struct GpFontCollection{
515c2c66affSColin Finck GpFontFamily **FontFamilies;
516c2c66affSColin Finck INT count;
517c2c66affSColin Finck INT allocated;
518c2c66affSColin Finck };
519c2c66affSColin Finck
520c2c66affSColin Finck struct GpFontFamily{
521c2c66affSColin Finck WCHAR FamilyName[LF_FACESIZE];
522c2c66affSColin Finck UINT16 em_height, ascent, descent, line_spacing; /* in font units */
523c2c66affSColin Finck int dpi;
524c2c66affSColin Finck };
525c2c66affSColin Finck
526c2c66affSColin Finck /* internal use */
527c2c66affSColin Finck typedef enum RegionType
528c2c66affSColin Finck {
529c2c66affSColin Finck RegionDataRect = 0x10000000,
530c2c66affSColin Finck RegionDataPath = 0x10000001,
531c2c66affSColin Finck RegionDataEmptyRect = 0x10000002,
532c2c66affSColin Finck RegionDataInfiniteRect = 0x10000003,
533c2c66affSColin Finck } RegionType;
534c2c66affSColin Finck
535c2c66affSColin Finck struct region_element
536c2c66affSColin Finck {
537c2c66affSColin Finck DWORD type; /* Rectangle, Path, SpecialRectangle, or CombineMode */
538c2c66affSColin Finck union
539c2c66affSColin Finck {
540c2c66affSColin Finck GpRectF rect;
541c2c66affSColin Finck GpPath *path;
542c2c66affSColin Finck struct
543c2c66affSColin Finck {
544c2c66affSColin Finck struct region_element *left; /* the original region */
545c2c66affSColin Finck struct region_element *right; /* what *left was combined with */
546c2c66affSColin Finck } combine;
547c2c66affSColin Finck } elementdata;
548c2c66affSColin Finck };
549c2c66affSColin Finck
550c2c66affSColin Finck struct GpRegion{
551c2c66affSColin Finck DWORD num_children;
552c2c66affSColin Finck region_element node;
553c2c66affSColin Finck };
554c2c66affSColin Finck
555007122e7SAmine Khaldi struct memory_buffer
556007122e7SAmine Khaldi {
557007122e7SAmine Khaldi const BYTE *buffer;
558007122e7SAmine Khaldi INT size, pos;
559007122e7SAmine Khaldi };
560007122e7SAmine Khaldi
init_memory_buffer(struct memory_buffer * mbuf,const BYTE * buffer,INT size)561007122e7SAmine Khaldi static inline void init_memory_buffer(struct memory_buffer *mbuf, const BYTE *buffer, INT size)
562007122e7SAmine Khaldi {
563007122e7SAmine Khaldi mbuf->buffer = buffer;
564007122e7SAmine Khaldi mbuf->size = size;
565007122e7SAmine Khaldi mbuf->pos = 0;
566007122e7SAmine Khaldi }
567007122e7SAmine Khaldi
buffer_read(struct memory_buffer * mbuf,INT size)568007122e7SAmine Khaldi static inline const void *buffer_read(struct memory_buffer *mbuf, INT size)
569007122e7SAmine Khaldi {
570007122e7SAmine Khaldi if (mbuf->size - mbuf->pos >= size)
571007122e7SAmine Khaldi {
572007122e7SAmine Khaldi const void *data = mbuf->buffer + mbuf->pos;
573007122e7SAmine Khaldi mbuf->pos += size;
574007122e7SAmine Khaldi return data;
575007122e7SAmine Khaldi }
576007122e7SAmine Khaldi return NULL;
577007122e7SAmine Khaldi }
578007122e7SAmine Khaldi
579c2c66affSColin Finck typedef GpStatus (*gdip_format_string_callback)(HDC hdc,
580c2c66affSColin Finck GDIPCONST WCHAR *string, INT index, INT length, GDIPCONST GpFont *font,
581c2c66affSColin Finck GDIPCONST RectF *rect, GDIPCONST GpStringFormat *format,
582c2c66affSColin Finck INT lineno, const RectF *bounds, INT *underlined_indexes,
583c2c66affSColin Finck INT underlined_index_count, void *user_data);
584c2c66affSColin Finck
585c2c66affSColin Finck GpStatus gdip_format_string(HDC hdc,
586c2c66affSColin Finck GDIPCONST WCHAR *string, INT length, GDIPCONST GpFont *font,
587c2c66affSColin Finck GDIPCONST RectF *rect, GDIPCONST GpStringFormat *format, int ignore_empty_clip,
588c2c66affSColin Finck gdip_format_string_callback callback, void *user_data) DECLSPEC_HIDDEN;
589c2c66affSColin Finck
590c2c66affSColin Finck void get_log_fontW(const GpFont *, GpGraphics *, LOGFONTW *) DECLSPEC_HIDDEN;
591c2c66affSColin Finck
image_lock(GpImage * image,BOOL * unlock)592c2c66affSColin Finck static inline BOOL image_lock(GpImage *image, BOOL *unlock)
593c2c66affSColin Finck {
594c2c66affSColin Finck LONG tid = GetCurrentThreadId(), owner_tid;
595c2c66affSColin Finck owner_tid = InterlockedCompareExchange(&image->busy, tid, 0);
596c2c66affSColin Finck *unlock = !owner_tid;
597c2c66affSColin Finck return !owner_tid || owner_tid==tid;
598c2c66affSColin Finck }
599c2c66affSColin Finck
image_unlock(GpImage * image,BOOL unlock)600c2c66affSColin Finck static inline void image_unlock(GpImage *image, BOOL unlock)
601c2c66affSColin Finck {
602c2c66affSColin Finck if (unlock) image->busy = 0;
603c2c66affSColin Finck }
604c2c66affSColin Finck
6055f279f2dSAmine Khaldi #endif
606