OLD | NEW |
---|---|
(Empty) | |
1 Creating SkCanvas Objects | |
2 ========================= | |
3 | |
4 All drawing commands in Skia take place via the `SkCanvas` API. | |
5 Here is an example of a set of drawing commands to draw a filled | |
6 heptagram. This function can be cut and pasted into | |
7 [fiddle.skia.org](https://fiddle.skia.org/). | |
8 | |
9 <!--?prettify lang=cc?--> | |
10 | |
11 #include "SkCanvas" | |
12 #include "SkPath" | |
13 void draw(SkCanvas* canvas) { | |
14 float scale = 256.0f; | |
reed1
2015/05/13 15:44:16
Lets use SkScalar in the dox
hal.canary
2015/05/13 17:58:24
Done.
| |
15 canvas->translate(0.5f * scale, 0.5f * scale); | |
16 canvas->clear(SK_ColorWHITE); | |
reed1
2015/05/13 15:44:16
logically, we should probably issue the clear firs
hal.canary
2015/05/13 17:58:24
Done.
| |
17 SkPath path; | |
18 float R = 0.45f * scale; | |
19 float TAU = 6.2831853f; | |
20 for (int i = 0; i < 7; ++i) { | |
21 float theta = 3 * i * TAU / 7; | |
22 if (i == 0) { | |
23 path.moveTo(R * cos(theta), R * sin(theta)); | |
24 } else { | |
25 path.lineTo(R * cos(theta), R * sin(theta)); | |
26 } | |
27 } | |
28 path.close(); | |
29 SkPaint p; | |
30 p.setAntiAlias(true); | |
31 canvas->drawPath(path, p); | |
32 } | |
33 | |
34 Skia has multiple backends which receive SkCanvas drawing commands, | |
35 including Raster (CPU-only), Ganesh (Skia's GPU-accelerated | |
36 backend), SkPDF (PDF document creation), and Picture (Skia's | |
37 display list format). | |
38 | |
39 Each backend has a unique way of createing a SkCanvas. The | |
40 recommended way of creating a canvas for the Raster and Ganesh | |
41 backends is to use a SkSurface, which is an object that manages the | |
42 memory into which the canvas commands are drawn. The SkPDF and | |
43 SkPicture backends uses SkDocument and SkPictureRecorder for the | |
44 same purpose. | |
45 | |
46 1. Raster: | |
47 | |
48 <!--?prettify lang=cc?--> | |
49 | |
50 #include "SkData.h" | |
51 #include "SkImage.h" | |
52 #include "SkStream.h" | |
53 #include "SkSurface.h" | |
54 void raster(int width, int height, | |
55 void(*drawable)(SkCanvas*), | |
scroggo
2015/05/13 14:51:15
nit: Since this is a function pointer, I'm not sur
hal.canary
2015/05/13 17:58:24
Done.
| |
56 const char* path) { | |
57 SkAutoTUnref<SkSurface> rasterSurface( | |
58 SkSurface::NewRasterN32Premul(width, height)); | |
59 SkCanvas* rasterCanvas = rasterSurface->getCanvas(); | |
60 | |
61 drawable(rasterCanvas); | |
62 | |
63 SkAutoTUnref<SkImage> img(s->newImageSnapshot()); | |
64 if (!img) { return; } | |
65 SkAutoTUnref<SkData> png(img->encode()); | |
66 if (!png) { return; } | |
67 SkFILEWStream out(path); | |
68 (void)out.write(png->data(), png->size()); | |
69 } | |
70 | |
71 2. Ganesh: | |
72 | |
73 <!--?prettify lang=cc?--> | |
74 | |
75 #include "GrContextFactory.h" | |
76 #include "SkData.h" | |
77 #include "SkImage.h" | |
78 #include "SkStream.h" | |
79 #include "SkSurface.h" | |
80 void ganesh(int width, int height, | |
81 void(*drawable)(SkCanvas*), | |
82 const char* path) { | |
83 GrContextFactory grFactory; | |
84 GrContext* context = grFactory.get(GrContextFactory::kNative_GLConte xtType); | |
85 SkImageInfo info = SkImageInfo:: MakeN32Premul(width, height); | |
86 SkAutoTUnref<SkSurface> gpuSurface( | |
87 SkSurface::NewRenderTarget(context, SkSurface::kNo_Budgeted, info)); | |
88 if (!gpuSurface) { | |
89 SkDebugf("SkSurface::NewRenderTarget returned null\n"); | |
90 return; | |
91 } | |
92 SkCanvas* gpuCanvas = gpuSurface->getCanvas(); | |
93 | |
94 drawable(gpuCanvas); | |
95 | |
96 SkAutoTUnref<SkImage> img(s->newImageSnapshot()); | |
97 if (!img) { return; } | |
98 SkAutoTUnref<SkData> png(img->encode()); | |
99 if (!png) { return; } | |
100 SkFILEWStream out(path); | |
101 (void)out.write(png->data(), png->size()); | |
102 | |
103 } | |
104 | |
105 3. SkPDF: | |
106 | |
107 <!--?prettify lang=cc?--> | |
108 | |
109 #include "SkDocument.h" | |
110 #include "SkStream.h" | |
111 void skpdf(int width, int height, | |
112 void(*drawable)(SkCanvas*), | |
113 const char* path) { | |
114 SkFILEWStream pdfStream(path); | |
115 SkAutoTUnref<SkDocument> pdfDoc(SkDocument::CreatePDF(&pdfStream)); | |
116 SkCanvas* pdfCanvas = pdfDoc->beginPage(SkIntToScalar(width), | |
117 SkIntToScalar(height)); | |
118 drawable(pdfCanvas); | |
119 pdfDoc->close(); | |
120 } | |
121 | |
122 3. SkPicture: | |
123 | |
124 <!--?prettify lang=cc?--> | |
125 | |
126 #include "SkPictureRecorder" | |
127 #include "SkPicture" | |
128 #include "SkStream.h" | |
129 void picture(int width, int height, | |
130 void(*drawable)(SkCanvas*), | |
131 const char* path) { | |
132 SkPictureRecorder recorder; | |
133 SkCanvas* recordingCanvas = recorder.beginRecording(SkIntToScalar(wi dth), | |
134 SkIntToScalar(he ight)); | |
135 drawable(recordingCanvas); | |
136 SkAutoTUnref<SkPicture> picture(recorder.endRecordingAsPicture()); | |
137 SkFILEWStream skpStream(path); | |
138 // Open SKP files with `SampleApp --picture SKP_FILE` | |
139 picture->serialize(&skpStream); | |
140 } | |
141 | |
142 | |
143 To try this code out, make a [new unit test using instructions | |
144 here](/dev/testing/tests) and wrap these funtions together: | |
145 | |
146 <!--?prettify lang=cc?--> | |
147 | |
148 #include "Test.h" | |
149 DEF_TEST(FourBackends, r) { | |
scroggo
2015/05/13 14:51:15
A danger in telling the user to copy and paste cod
hal.canary
2015/05/13 17:58:24
Acknowledged.
| |
150 raster( 256, 256, draw, "out_raster.png" ); | |
151 ganesh( 256, 256, draw, "out_ganesh.png" ); | |
152 skpdf( 256, 256, draw, "out_skpdf.pdf" ); | |
153 picture(256, 256, draw, "out_picture.skp"); | |
154 } | |
OLD | NEW |