Chromium Code Reviews| 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 |