-
Notifications
You must be signed in to change notification settings - Fork 544
Expand file tree
/
Copy pathRGraphics.cs
More file actions
319 lines (281 loc) · 14.6 KB
/
RGraphics.cs
File metadata and controls
319 lines (281 loc) · 14.6 KB
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
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
// "Therefore those skilled at the unorthodox
// are infinite as heaven and earth,
// inexhaustible as the great rivers.
// When they come to an end,
// they begin again,
// like the days and months;
// they die and are reborn,
// like the four seasons."
//
// - Sun Tsu,
// "The Art of War"
using System;
using System.Collections.Generic;
using TheArtOfDev.HtmlRenderer.Adapters.Entities;
using TheArtOfDev.HtmlRenderer.Core.Utils;
namespace TheArtOfDev.HtmlRenderer.Adapters
{
/// <summary>
/// Adapter for platform specific graphics rendering object - used to render graphics and text in platform specific context.<br/>
/// The core HTML Renderer components use this class for rendering logic, extending this
/// class in different platform: WinForms, WPF, Metro, PDF, etc.
/// </summary>
public abstract class RGraphics : IDisposable
{
#region Fields/Consts
/// <summary>
/// the global adapter
/// </summary>
protected readonly RAdapter _adapter;
/// <summary>
/// The clipping bound stack as clips are pushed/poped to/from the graphics
/// </summary>
protected readonly Stack<RRect> _clipStack = new Stack<RRect>();
/// <summary>
/// The suspended clips
/// </summary>
private Stack<RRect> _suspendedClips = new Stack<RRect>();
#endregion
/// <summary>
/// Init.
/// </summary>
protected RGraphics(RAdapter adapter, RRect initialClip)
{
ArgChecker.AssertArgNotNull(adapter, "global");
_adapter = adapter;
_clipStack.Push(initialClip);
}
/// <summary>
/// Get color pen.
/// </summary>
/// <param name="color">the color to get the pen for</param>
/// <returns>pen instance</returns>
public RPen GetPen(RColor color)
{
return _adapter.GetPen(color);
}
/// <summary>
/// Get solid color brush.
/// </summary>
/// <param name="color">the color to get the brush for</param>
/// <returns>solid color brush instance</returns>
public RBrush GetSolidBrush(RColor color)
{
return _adapter.GetSolidBrush(color);
}
/// <summary>
/// Get linear gradient color brush from <paramref name="color1"/> to <paramref name="color2"/>.
/// </summary>
/// <param name="rect">the rectangle to get the brush for</param>
/// <param name="color1">the start color of the gradient</param>
/// <param name="color2">the end color of the gradient</param>
/// <param name="angle">the angle to move the gradient from start color to end color in the rectangle</param>
/// <returns>linear gradient color brush instance</returns>
public RBrush GetLinearGradientBrush(RRect rect, RColor color1, RColor color2, double angle)
{
return _adapter.GetLinearGradientBrush(rect, color1, color2, angle);
}
/// <summary>
/// Gets a Rectangle structure that bounds the clipping region of this Graphics.
/// </summary>
/// <returns>A rectangle structure that represents a bounding rectangle for the clipping region of this Graphics.</returns>
public RRect GetClip()
{
return _clipStack.Peek();
}
/// <summary>
/// Pop the latest clip push.
/// </summary>
public abstract void PopClip();
/// <summary>
/// Push the clipping region of this Graphics to interception of current clipping rectangle and the given rectangle.
/// </summary>
/// <param name="rect">Rectangle to clip to.</param>
public abstract void PushClip(RRect rect);
/// <summary>
/// Push the clipping region of this Graphics to exclude the given rectangle from the current clipping rectangle.
/// </summary>
/// <param name="rect">Rectangle to exclude clipping in.</param>
public abstract void PushClipExclude(RRect rect);
/// <summary>
/// Restore the clipping region to the initial clip.
/// </summary>
public void SuspendClipping()
{
while (_clipStack.Count > 1)
{
var clip = GetClip();
_suspendedClips.Push(clip);
PopClip();
}
}
/// <summary>
/// Resumes the suspended clips.
/// </summary>
public void ResumeClipping()
{
while (_suspendedClips.Count > 0)
{
var clip = _suspendedClips.Pop();
PushClip(clip);
}
}
/// <summary>
/// Set the graphics smooth mode to use anti-alias.<br/>
/// Use <see cref="ReturnPreviousSmoothingMode"/> to return back the mode used.
/// </summary>
/// <returns>the previous smooth mode before the change</returns>
public abstract Object SetAntiAliasSmoothingMode();
/// <summary>
/// Return to previous smooth mode before anti-alias was set as returned from <see cref="SetAntiAliasSmoothingMode"/>.
/// </summary>
/// <param name="prevMode">the previous mode to set</param>
public abstract void ReturnPreviousSmoothingMode(Object prevMode);
/// <summary>
/// Get TextureBrush object that uses the specified image and bounding rectangle.
/// </summary>
/// <param name="image">The Image object with which this TextureBrush object fills interiors.</param>
/// <param name="dstRect">A Rectangle structure that represents the bounding rectangle for this TextureBrush object.</param>
/// <param name="translateTransformLocation">The dimension by which to translate the transformation</param>
public abstract RBrush GetTextureBrush(RImage image, RRect dstRect, RPoint translateTransformLocation);
/// <summary>
/// Get GraphicsPath object.
/// </summary>
/// <returns>graphics path instance</returns>
public abstract RGraphicsPath GetGraphicsPath();
/// <summary>
/// Measure the width and height of string <paramref name="str"/> when drawn on device context HDC
/// using the given font <paramref name="font"/>.
/// </summary>
/// <param name="str">the string to measure</param>
/// <param name="font">the font to measure string with</param>
/// <returns>the size of the string</returns>
public abstract RSize MeasureString(string str, RFont font);
/// <summary>
/// Measure the width and height of string <paramref name="str"/> when drawn on device context HDC
/// using the given fonts: <paramref name="regularFont"/> <paramref name="reducedFont"/> (small-caps variant).
/// </summary>
/// <param name="str">the string to measure</param>
/// <param name="regularFont">the font to measure string with (uppercase chars)</param>
/// <param name="reducedFont">the font to measure string with (smallcap chars)</param>
/// <returns>the size of the string</returns>
public RSize MeasureSmallCapString(string str, RFont regularFont, RFont reducedFont)
{
RSize size = RSize.Empty;
size.Height = regularFont.Height;
int i = 0;
int len = str.Length;
while (i < len)
{
int j = i;
while (j < len && !char.IsLower(str, j))
j++;
if (j != i)
{
size.Width += MeasureString(str.Substring(i, j - i), regularFont).Width;
i = j;
}
while (j < len && char.IsLower(str, j))
j++;
if (j != i)
{
size.Width += MeasureString(str.Substring(i, j - i).ToUpper(), reducedFont).Width;
i = j;
}
}
return size;
}
/// <summary>
/// Measure the width of string under max width restriction calculating the number of characters that can fit and the width those characters take.<br/>
/// Not relevant for platforms that don't render HTML on UI element.
/// </summary>
/// <param name="str">the string to measure</param>
/// <param name="font">the font to measure string with</param>
/// <param name="maxWidth">the max width to calculate fit characters</param>
/// <param name="charFit">the number of characters that will fit under <see cref="maxWidth"/> restriction</param>
/// <param name="charFitWidth">the width that only the characters that fit into max width take</param>
public abstract void MeasureString(string str, RFont font, double maxWidth, out int charFit, out double charFitWidth);
/// <summary>
/// Draw the given string using the given font and foreground color at given location.
/// </summary>
/// <param name="str">the string to draw</param>
/// <param name="font">the font to use to draw the string</param>
/// <param name="color">the text color to set</param>
/// <param name="point">the location to start string draw (top-left)</param>
/// <param name="size">used to know the size of the rendered text for transparent text support</param>
/// <param name="rtl">is to render the string right-to-left (true - RTL, false - LTR)</param>
public abstract void DrawString(String str, RFont font, RColor color, RPoint point, RSize size, bool rtl);
/// <summary>
/// Draw the given string using the given fonts and foreground color at given location (small-caps variant).
/// </summary>
/// <param name="str">the string to draw</param>
/// <param name="regularFont">the font to use to draw the string (uppercase chars)</param>
/// <param name="reducedFont">the reduced font to use to draw the string (small-cap chars)</param>
/// <param name="color">the text color to set</param>
/// <param name="point">the location to start string draw (top-left)</param>
/// <param name="rtl">is to render the string right-to-left (true - RTL, false - LTR)</param>
public abstract void DrawSmallCapString(string str, RFont regularFont, RFont reducedFont, RColor color, RPoint point, bool rtl);
/// <summary>
/// Draws a line connecting the two points specified by the coordinate pairs.
/// </summary>
/// <param name="pen">Pen that determines the color, width, and style of the line. </param>
/// <param name="x1">The x-coordinate of the first point. </param>
/// <param name="y1">The y-coordinate of the first point. </param>
/// <param name="x2">The x-coordinate of the second point. </param>
/// <param name="y2">The y-coordinate of the second point. </param>
public abstract void DrawLine(RPen pen, double x1, double y1, double x2, double y2);
/// <summary>
/// Draws a rectangle specified by a coordinate pair, a width, and a height.
/// </summary>
/// <param name="pen">A Pen that determines the color, width, and style of the rectangle. </param>
/// <param name="x">The x-coordinate of the upper-left corner of the rectangle to draw. </param>
/// <param name="y">The y-coordinate of the upper-left corner of the rectangle to draw. </param>
/// <param name="width">The width of the rectangle to draw. </param>
/// <param name="height">The height of the rectangle to draw. </param>
public abstract void DrawRectangle(RPen pen, double x, double y, double width, double height);
/// <summary>
/// Fills the interior of a rectangle specified by a pair of coordinates, a width, and a height.
/// </summary>
/// <param name="brush">Brush that determines the characteristics of the fill. </param>
/// <param name="x">The x-coordinate of the upper-left corner of the rectangle to fill. </param>
/// <param name="y">The y-coordinate of the upper-left corner of the rectangle to fill. </param>
/// <param name="width">Width of the rectangle to fill. </param>
/// <param name="height">Height of the rectangle to fill. </param>
public abstract void DrawRectangle(RBrush brush, double x, double y, double width, double height);
/// <summary>
/// Draws the specified portion of the specified <see cref="RImage"/> at the specified location and with the specified size.
/// </summary>
/// <param name="image">Image to draw. </param>
/// <param name="destRect">Rectangle structure that specifies the location and size of the drawn image. The image is scaled to fit the rectangle. </param>
/// <param name="srcRect">Rectangle structure that specifies the portion of the <paramref name="image"/> object to draw. </param>
public abstract void DrawImage(RImage image, RRect destRect, RRect srcRect);
/// <summary>
/// Draws the specified Image at the specified location and with the specified size.
/// </summary>
/// <param name="image">Image to draw. </param>
/// <param name="destRect">Rectangle structure that specifies the location and size of the drawn image. </param>
public abstract void DrawImage(RImage image, RRect destRect);
/// <summary>
/// Draws a GraphicsPath.
/// </summary>
/// <param name="pen">Pen that determines the color, width, and style of the path. </param>
/// <param name="path">GraphicsPath to draw. </param>
public abstract void DrawPath(RPen pen, RGraphicsPath path);
/// <summary>
/// Fills the interior of a GraphicsPath.
/// </summary>
/// <param name="brush">Brush that determines the characteristics of the fill. </param>
/// <param name="path">GraphicsPath that represents the path to fill. </param>
public abstract void DrawPath(RBrush brush, RGraphicsPath path);
/// <summary>
/// Fills the interior of a polygon defined by an array of points specified by Point structures.
/// </summary>
/// <param name="brush">Brush that determines the characteristics of the fill. </param>
/// <param name="points">Array of Point structures that represent the vertices of the polygon to fill. </param>
public abstract void DrawPolygon(RBrush brush, RPoint[] points);
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public abstract void Dispose();
}
}