~yves-piguet/npw/trunk

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
/**
 *	@file NPWGraphics.h
 *	@brief Helper functions for graphics
 *	@author Yves Piguet.
 *	@copyright 2008-2014, Yves Piguet
 */

#ifndef __NPWGraphics__
#define __NPWGraphics__

#ifdef __cplusplus
extern "C" {
#endif

#include "NPWBase.h"

/**	Write arguments and a command.
	@param pdf reference to NPW structure
	@param[in] cmd PDF command
	@param[in] fmt argument types (f=float, i=int, S=raw string+len, s=PDF string+len)
	@return error code (kNPWErrOk for success)
*/
NPWErr NPWGraphicsCmd(NPW *pdf, NPWConstText cmd, NPWConstText fmt, ...);

/// Path "move" command
#define NPWGraphicsMove(pdf, x, y) \
	NPWGraphicsCmd(pdf, "m", "ff", (NPWFloat)(x), (NPWFloat)(y))
/// Path "line" command
#define NPWGraphicsLine(pdf, x, y) \
	NPWGraphicsCmd(pdf, "l", "ff", (NPWFloat)(x), (NPWFloat)(y))
/// Path "bezier" command
#define NPWGraphicsBezier(pdf, x1, y1, x2, y2, x3, y3) \
	NPWGraphicsCmd(pdf, "c", "ffffff", \
		(NPWFloat)(x1), (NPWFloat)(y1), (NPWFloat)(x2), (NPWFloat)(y2), (NPWFloat)(x3), (NPWFloat)(y3))
/// Close path
#define NPWGraphicsClosePath(pdf) \
	NPWGraphicsCmd(pdf, "h", "")
/// Create a rectangular path
#define NPWGraphicsRectangle(pdf, x, y, w, h) \
	NPWGraphicsCmd(pdf, "re", "ffff", (NPWFloat)(x), (NPWFloat)(y), (NPWFloat)(w), (NPWFloat)(h))

/// Create an elliptic path
#define NPWGraphicsEllipse(pdf, x0, y0, rx, ry) \
	do { \
		NPWGraphicsMove(pdf, (x0) - (rx), y0); \
		NPWGraphicsBezier(pdf, \
				(x0) - (rx), (y0) + (ry) * 55 / 100, \
				(x0) - (rx) * 55 / 100, (y0) + (ry), \
				x0, (y0) + (ry)); \
		NPWGraphicsBezier(pdf, \
				(x0) + (rx) * 55 / 100, (y0) + (ry), \
				(x0) + (rx), (y0) + (ry) * 55 / 100, \
				(x0) + (rx), y0); \
		NPWGraphicsBezier(pdf, \
				(x0) + (rx), (y0) - (ry) * 55 / 100, \
				(x0) + (rx) * 55 / 100, (y0) - (ry), \
				x0, (y0) - (ry)); \
		NPWGraphicsBezier(pdf, \
				(x0) - (rx) * 55 / 100, (y0) - (ry), \
				(x0) - (rx), (y0) - (ry) * 55 / 100, \
				(x0) - (rx), y0); \
		NPWGraphicsClosePath(pdf); \
	} while (0)

/// Stroke path
#define NPWGraphicsStroke(pdf) \
	NPWGraphicsCmd(pdf, "S", "")
/// Close and stroke path
#define NPWGraphicsCloseStroke(pdf) \
	NPWGraphicsCmd(pdf, "s", "")
/// Fill path using nonzero winding number rule
#define NPWGraphicsFill(pdf) \
	NPWGraphicsCmd(pdf, "f", "")
/// Fill path using even-odd rule
#define NPWGraphicsFillEO(pdf) \
	NPWGraphicsCmd(pdf, "f*", "")
/// Fill path using nonzero winding number rule, then stroke it
#define NPWGraphicsFillStroke(pdf) \
	NPWGraphicsCmd(pdf, "B", "")
/// Fill path using even-odd rule, then stroke it
#define NPWGraphicsFillEOStroke(pdf) \
	NPWGraphicsCmd(pdf, "B*", "")
/// Close path, fill it using nonzero winding number rule, then stroke it
#define NPWGraphicsCloseFillStroke(pdf) \
	NPWGraphicsCmd(pdf, "b", "")
/// Close path, fill it using even-odd rule, then stroke it
#define NPWGraphicsCloseFillEOStroke(pdf) \
	NPWGraphicsCmd(pdf, "b*", "")
/// Discard path
#define NPWGraphicsEndPath(pdf) \
	NPWGraphicsCmd(pdf, "n", "")

/// Use path to define the clipping region with nonzero winding number rule
#define NPWGraphicsClip(pdf) \
	NPWGraphicsCmd(pdf, "W", "")
/// Use path to define the clipping region with even-odd rule
#define NPWGraphicsClipEO(pdf) \
	NPWGraphicsCmd(pdf, "W*", "")

/// Define the gray shade for stroking
#define NPWGraphicsGrayStroke(pdf, g) \
	NPWGraphicsCmd(pdf, "G", "f", (NPWFloat)(g))
/// Define the gray shade for filling
#define NPWGraphicsGray(pdf, g) \
	NPWGraphicsCmd(pdf, "g", "f", (NPWFloat)g)
/// Define the RGB color for stroking
#define NPWGraphicsRGBStroke(pdf, r, g, b) \
	NPWGraphicsCmd(pdf, "RG", "fff", (NPWFloat)(r), (NPWFloat)(g), (NPWFloat)(b))
/// Define the RGB color for filling
#define NPWGraphicsRGB(pdf, r, g, b) \
	NPWGraphicsCmd(pdf, "rg", "fff", (NPWFloat)(r), (NPWFloat)(g), (NPWFloat)(b))
/// Define the CMYK color for stroking
#define NPWGraphicsCMYKStroke(pdf, c, m, y, k) \
	NPWGraphicsCmd(pdf, "K", "ffff", (NPWFloat)(c), (NPWFloat)(m), (NPWFloat)(y), (NPWFloat)(k))
/// Define the CMYK color for filling
#define NPWGraphicsCMYK(pdf, c, m, y, k) \
	NPWGraphicsCmd(pdf, "k", "ffff", (NPWFloat)(c), (NPWFloat)(m), (NPWFloat)(y), (NPWFloat)(k))

/// Line cap type
enum
{
	kNPWLineCapButt = 0,	///< butt cap
	kNPWLineCapRound,	///< round cap
	kNPWLineCapSquare	///< square cap
};

/// Line join type
enum
{
	kNPWLineJoinMitter = 0,	///< mitter join
	kNPWLineJoinRound,	///< round join
	kNPWLineJoinBevel	///< bevel join
};

/// Save graphics state
#define NPWGraphicsSave(pdf) \
	NPWGraphicsCmd(pdf, "q", "")
/// Restore graphics state
#define NPWGraphicsRestore(pdf) \
	NPWGraphicsCmd(pdf, "Q", "")
/// Concatenate a matrix to the current coordinate transform matrix
#define NPWGraphicsConcatCTM(pdf, a, b, c, d, e, f) \
	NPWGraphicsCmd(pdf, "cm", "ffffff", \
		(NPWFloat)(a), (NPWFloat)(b), (NPWFloat)(c), (NPWFloat)(d), (NPWFloat)(e), (NPWFloat)(f))
/// Concatenate a translation matrix to the current coordinate transform matrix
#define NPWGraphicsTranslate(pdf, dx, dy) \
	NPWGraphicsConcatCTM(pdf, 1, 0, 0, 1, dx, dy)
/// Concatenate a scaling matrix to the current coordinate transform matrix
#define NPWGraphicsScale(pdf, sx, sy) \
	NPWGraphicsConcatCTM(pdf, sx, 0, 0, sy, 0, 0)
/// Set line width for stroking
#define NPWGraphicsSetLineWidth(pdf, w) \
	NPWGraphicsCmd(pdf, "w", "f", (NPWFloat)(w))
/// Set line cap
#define NPWGraphicsSetLineCap(pdf, c) \
	NPWGraphicsCmd(pdf, "J", "i", c)
/// Set line join
#define NPWGraphicsSetLineJoin(pdf, j) \
	NPWGraphicsCmd(pdf, "j", "i", j)
/// Set miter limit
#define NPWGraphicsSetMiterLimit(pdf, l) \
	NPWGraphicsCmd(pdf, "M", "f", (NPWFloat)(l))

/// Begin an inline raster image (must be followed by the raster data
/// written with NPWFilterBegin, NPWFilterWrite and NPWFilterEnd)
#define NPWInlineImageBegin(pdf, w, h, cs, bpc, f) \
	do { \
		NPWWrite(pdf, "BI\n/W ", -1); \
		NPWWriteInt(pdf, w, -1); \
		NPWWrite(pdf, "\n/H ", -1); \
		NPWWriteInt(pdf, h, -1); \
		NPWWrite(pdf, "\n/CS ", -1); \
		NPWWrite(pdf, cs, -1); \
		NPWWrite(pdf, "\n/BPC ", -1); \
		NPWWriteInt(pdf, bpc, -1); \
		NPWWrite(pdf, "\n/F ", -1); \
		NPWWrite(pdf, f, -1); \
		NPWWrite(pdf, "\nID ", -1); \
	} while (0)
/// End an inline image
#define NPWInlineImageEnd(pdf) \
	NPWWrite(pdf, "EI\n", -1);

/// Text rendering modes
enum
{
	kNPWTextRenderingModeFill = 0,	///< fill text (normal)
	kNPWTextRenderingModeStroke,	///< stroke text
	kNPWTextRenderingModeFillStroke,	///< fill, then stroke text
	kNPWTextRenderingModeInvisible,	///< do nothing (invisible)
	kNPWTextRenderingModeFillClip,	///< fill text and add to path for clipping
	kNPWTextRenderingModeStrokeClip,	///< stroke text and add to path for clipping
	kNPWTextRenderingModeFillStrokeClip,	///< fill, then stroke text and add to path for clipping
	kNPWTextRenderingModeClip	///< add text to path for clipping
};

/// Set additional space between each character pair (positive to reduce space)
#define NPWGraphicsSetCharSpace(pdf, s) \
	NPWGraphicsCmd(pdf, "Tc", "f", (NPWFloat)(s))
/// Set additional space between each word
#define NPWGraphicsSetWordSpace(pdf, s) \
	NPWGraphicsCmd(pdf, "Tw", "f", (NPWFloat)(s))
/// Set horizontal scaling
#define NPWGraphicsSetHorizontalScaling(pdf, s) \
	NPWGraphicsCmd(pdf, "Tz", "f", (NPWFloat)(s))
/// Set text leading (distance between lines, negative to go downward)
#define NPWGraphicsSetTextLeading(pdf, leading) \
	NPWGraphicsCmd(pdf, "TL", "f", (NPWFloat)(leading))
/// Set text font (NPWFontNameCourier etc.) and size
#define NPWGraphicsSetTextFont(pdf, font, size) \
	NPWGraphicsCmd(pdf, "Tf", "Sf", font, -1, (NPWFloat)(size))
/// Set text rendering mode (default = kNPWTextRenderingModeFill)
#define NPWGraphicsSetTextRenderingMode(pdf, render) \
	NPWGraphicsCmd(pdf, "Tr", "f", (NPWFloat)(render))
/// Set text rise (positive for superscript)
#define NPWGraphicsSetTextRise(pdf, rise) \
	NPWGraphicsCmd(pdf, "Ts", "f", (NPWFloat)(rise))

/// Begin writing text
#define NPWGraphicsBeginText(pdf) \
	NPWGraphicsCmd(pdf, "BT", "")
/// End writing text
#define NPWGraphicsEndText(pdf) \
	NPWGraphicsCmd(pdf, "ET", "")
/// Move position of next text drawing
#define NPWGraphicsMoveText(pdf, x, y) \
	NPWGraphicsCmd(pdf, "Td", "ff", (NPWFloat)(x), (NPWFloat)(y))
/// Move to beginning of next line
#define NPWGraphicsNL(pdf) \
	NPWGraphicsCmd(pdf, "T*", "")
/// Show text
#define NPWGraphicsShowText(pdf, str, len) \
	NPWGraphicsCmd(pdf, "Tj", "s", str, len)
/// Move to beginning of next line, then show text
#define NPWGraphicsNLShowText(pdf, str, len) \
	NPWGraphicsCmd(pdf, "'", "s", str, len)
/// Move to beginning of next line, set space between words and characters, then show text
#define NPWGraphicsNLShowTextSp(pdf, aw, ac, str, len) \
	NPWGraphicsCmd(pdf, "\"", "ffs", (NPWFloat)(aw), (NPWFloat)(ac), str, len)
/// Adjust horizontal displacement by moving to the right, in 1/1000 font size
#define NPWGraphicsHorSkip(pdf, dx) \
	NPWGraphicsCmd(pdf, "TJ", "[f]", -(NPWFloat)dx)

#ifdef __cplusplus
}
#endif

#endif