1 module skia.SKSurface; 2 3 import skia.Definitions; 4 import skia.MathTypes; 5 import skia.SKImageInfo; 6 import skia.SKPixmap; 7 import skia.GRContext; 8 import skia.GRDefinitions; 9 import skia.DelegateProxies; 10 import skia.GRBackendRenderTarget; 11 import skia.SkiaApi; 12 import skia.GRBackendTexture; 13 import skia.SKColorSpace; 14 import skia.SKSurfaceProperties; 15 import skia.SKImage; 16 import skia.SKCanvas; 17 import skia.SKPaint; 18 import skia.SKVertices; 19 import skia.SKObject; 20 import skia.Exceptions; 21 import skia.EnumMappings; 22 23 import std.experimental.logger; 24 25 class SKSurface : SKObject, ISKSkipObjectRegistration { 26 27 static SKSurface Create(int width, int height, SKColorType colorType, SKAlphaType alphaType) { 28 return Create(SKImageInfo(width, height, colorType, alphaType)); 29 } 30 31 static SKSurface Create(int width, int height, SKColorType colorType, 32 SKAlphaType alphaType, SKSurfaceProps props) { 33 return Create(SKImageInfo(width, height, colorType, alphaType), props); 34 } 35 36 static SKSurface Create(int width, int height, SKColorType colorType, 37 SKAlphaType alphaType, void* pixels, int rowBytes) { 38 return Create(SKImageInfo(width, height, colorType, alphaType), pixels, rowBytes); 39 } 40 41 static SKSurface Create(int width, int height, SKColorType colorType, 42 SKAlphaType alphaType, void* pixels, int rowBytes, SKSurfaceProps props) { 43 return Create(SKImageInfo(width, height, colorType, alphaType), pixels, rowBytes, props); 44 } 45 46 this(void* h, bool owns) { 47 super(h, owns); 48 } 49 50 // protected override void Dispose (bool disposing) 51 // { 52 // return super.Dispose (disposing); 53 // } 54 55 // RASTER surface 56 57 static SKSurface Create(SKImageInfo info, SKSurfaceProps props) { 58 return Create(info, 0, new SKSurfaceProperties(props)); 59 } 60 61 static SKSurface Create(SKImageInfo info) { 62 return Create(info, 0, null); 63 } 64 65 static SKSurface Create(SKImageInfo info, int rowBytes) { 66 return Create(info, rowBytes, null); 67 } 68 69 static SKSurface Create(SKImageInfo info, SKSurfaceProperties props) { 70 return Create(info, 0, props); 71 } 72 73 static SKSurface Create(SKImageInfo info, int rowBytes, SKSurfaceProperties props) { 74 auto cinfo = SKImageInfo.FromManaged(info); 75 void* handle = null; 76 if(props !is null && props.Handle !is null) { 77 handle = props.Handle; 78 } 79 return GetObject(SkiaApi.sk_surface_new_raster(&cinfo, cast(void*) rowBytes, 80 cast(sk_surfaceprops_t*)handle)); 81 } 82 83 // convenience RASTER DIRECT to use a SKPixmap instead of SKImageInfo and void* 84 85 static SKSurface Create(SKPixmap pixmap, SKSurfaceProps props) { 86 return Create(pixmap, new SKSurfaceProperties(props)); 87 } 88 89 static SKSurface Create(SKPixmap pixmap) { 90 return Create(pixmap, null); 91 } 92 93 static SKSurface Create(SKPixmap pixmap, SKSurfaceProperties props) { 94 if (pixmap is null) { 95 throw new ArgumentNullException(pixmap.stringof); 96 } 97 return Create(pixmap.Info, pixmap.GetPixels(), pixmap.RowBytes, props); 98 } 99 100 // RASTER DIRECT surface 101 102 static SKSurface Create(SKImageInfo info, void* pixels, int rowBytes, SKSurfaceProps props) { 103 return Create(info, pixels, rowBytes, new SKSurfaceProperties(props)); 104 } 105 106 static SKSurface Create(SKImageInfo info, void* pixels) { 107 return Create(info, pixels, info.RowBytes); 108 } 109 110 static SKSurface Create(SKImageInfo info, void* pixels, int rowBytes) { 111 return Create(info, pixels, rowBytes); 112 } 113 114 // static SKSurface Create (SKImageInfo info, void* pixels, int rowBytes, SKSurfaceReleaseDelegate releaseProc, object context) 115 // { 116 // return Create (info, pixels, rowBytes, releaseProc, context, null); 117 // } 118 119 static SKSurface Create(SKImageInfo info, void* pixels, SKSurfaceProperties props) { 120 return Create(info, pixels, info.RowBytes, props); 121 } 122 123 static SKSurface Create(SKImageInfo info, void* pixels, int rowBytes, 124 SKSurfaceProperties props) { 125 return Create(info, pixels, rowBytes, props); 126 } 127 128 // static SKSurface Create (SKImageInfo info, void* pixels, int rowBytes, SKSurfaceReleaseDelegate releaseProc, object context, SKSurfaceProperties props) 129 // { 130 // auto cinfo = SKImageInfo.FromManaged (ref info); 131 // auto del = releaseProc !is null && context !is null 132 // ? new SKSurfaceReleaseDelegate ((addr, _) {return releaseProc (addr, context);}) 133 // : releaseProc; 134 // auto proxy = DelegateProxies.Create (del, DelegateProxies.SKSurfaceReleaseDelegateProxy, _, out var ctx); 135 // return GetObject (SkiaApi.sk_surface_new_raster_direct (&cinfo, cast(void*)pixels, cast(void*)rowBytes, proxy, cast(void*)ctx, props.Handle ? props.Handle : null)); 136 // } 137 138 // GPU BACKEND RENDER TARGET surface 139 140 static SKSurface Create(GRContext context, GRBackendRenderTargetDesc desc) { 141 if (context is null) 142 throw new ArgumentNullException(context.stringof); 143 144 auto renderTarget = new GRBackendRenderTarget(context.Backend, desc); 145 return Create(context, renderTarget, desc.Origin, desc.Config.ToColorType(), null, null); 146 } 147 148 static SKSurface Create(GRContext context, GRBackendRenderTargetDesc desc, SKSurfaceProps props) { 149 if (context is null) 150 throw new ArgumentNullException(context.stringof); 151 152 auto renderTarget = new GRBackendRenderTarget(context.Backend, desc); 153 return Create(context, renderTarget, desc.Origin, 154 desc.Config.ToColorType(), null, new SKSurfaceProperties(props)); 155 } 156 157 static SKSurface Create(GRContext context, 158 GRBackendRenderTarget renderTarget, SKColorType colorType) { 159 return Create(context, renderTarget, GRSurfaceOrigin.BottomLeft, colorType, null, null); 160 } 161 162 static SKSurface Create(GRContext context, GRBackendRenderTarget renderTarget, 163 GRSurfaceOrigin origin, SKColorType colorType) { 164 return Create(context, renderTarget, origin, colorType, null, null); 165 } 166 167 static SKSurface Create(GRContext context, GRBackendRenderTarget renderTarget, 168 GRSurfaceOrigin origin, SKColorType colorType, SKColorSpace colorspace) { 169 return Create(context, renderTarget, origin, colorType, colorspace, null); 170 } 171 172 static SKSurface Create(GRContext context, GRBackendRenderTarget renderTarget, 173 SKColorType colorType, SKSurfaceProperties props) { 174 return Create(context, renderTarget, GRSurfaceOrigin.BottomLeft, colorType, null, props); 175 } 176 177 static SKSurface Create(GRContext context, GRBackendRenderTarget renderTarget, 178 GRSurfaceOrigin origin, SKColorType colorType, SKSurfaceProperties props) { 179 return Create(context, renderTarget, origin, colorType, null, props); 180 } 181 182 static SKSurface Create(GRContext context, GRBackendRenderTarget renderTarget, 183 GRSurfaceOrigin origin, SKColorType colorType, 184 SKColorSpace colorspace, SKSurfaceProperties props) { 185 if (context is null) 186 throw new ArgumentNullException(context.stringof); 187 if (renderTarget is null) 188 throw new ArgumentNullException(renderTarget.stringof); 189 190 return GetObject(SkiaApi.sk_surface_new_backend_render_target(cast(gr_context_t*) context.Handle, 191 cast(gr_backendrendertarget_t*) renderTarget.Handle, origin, ToNative(colorType), 192 cast(sk_colorspace_t*)(colorspace.Handle ? colorspace.Handle : null), 193 cast(sk_surfaceprops_t*)(props.Handle ? props.Handle : null))); 194 } 195 196 // GPU BACKEND TEXTURE surface 197 198 static SKSurface Create(GRContext context, GRGlBackendTextureDesc desc) { 199 return Create(context, new GRBackendTexture(desc), desc.Origin, 200 desc.SampleCount, desc.Config.ToColorType(), null, null); 201 } 202 203 static SKSurface Create(GRContext context, GRBackendTextureDesc desc) { 204 return Create(context, new GRBackendTexture(desc), desc.Origin, 205 desc.SampleCount, desc.Config.ToColorType(), null, null); 206 } 207 208 static SKSurface Create(GRContext context, GRGlBackendTextureDesc desc, SKSurfaceProps props) { 209 return Create(context, new GRBackendTexture(desc), desc.Origin, desc.SampleCount, 210 desc.Config.ToColorType(), null, new SKSurfaceProperties(props)); 211 } 212 213 static SKSurface Create(GRContext context, GRBackendTextureDesc desc, SKSurfaceProps props) { 214 return Create(context, new GRBackendTexture(desc), desc.Origin, desc.SampleCount, 215 desc.Config.ToColorType(), null, new SKSurfaceProperties(props)); 216 } 217 218 static SKSurface Create(GRContext context, GRBackendTexture texture, SKColorType colorType) { 219 return Create(context, texture, GRSurfaceOrigin.BottomLeft, 0, colorType, null, null); 220 } 221 222 static SKSurface Create(GRContext context, GRBackendTexture texture, 223 GRSurfaceOrigin origin, SKColorType colorType) { 224 return Create(context, texture, origin, 0, colorType, null, null); 225 } 226 227 static SKSurface Create(GRContext context, GRBackendTexture texture, 228 GRSurfaceOrigin origin, int sampleCount, SKColorType colorType) { 229 return Create(context, texture, origin, sampleCount, colorType, null, null); 230 } 231 232 static SKSurface Create(GRContext context, GRBackendTexture texture, 233 GRSurfaceOrigin origin, int sampleCount, SKColorType colorType, SKColorSpace colorspace) { 234 return Create(context, texture, origin, sampleCount, colorType, colorspace, null); 235 } 236 237 static SKSurface Create(GRContext context, GRBackendTexture texture, 238 SKColorType colorType, SKSurfaceProperties props) { 239 return Create(context, texture, GRSurfaceOrigin.BottomLeft, 0, colorType, null, props); 240 } 241 242 static SKSurface Create(GRContext context, GRBackendTexture texture, 243 GRSurfaceOrigin origin, SKColorType colorType, SKSurfaceProperties props) { 244 return Create(context, texture, origin, 0, colorType, null, props); 245 } 246 247 static SKSurface Create(GRContext context, GRBackendTexture texture, 248 GRSurfaceOrigin origin, int sampleCount, SKColorType colorType, 249 SKSurfaceProperties props) { 250 return Create(context, texture, origin, sampleCount, colorType, null, props); 251 } 252 253 static SKSurface Create(GRContext context, GRBackendTexture texture, GRSurfaceOrigin origin, 254 int sampleCount, SKColorType colorType, SKColorSpace colorspace, 255 SKSurfaceProperties props) { 256 if (context is null) 257 throw new ArgumentNullException(context.stringof); 258 if (texture is null) 259 throw new ArgumentNullException(texture.stringof); 260 261 return GetObject(SkiaApi.sk_surface_new_backend_texture(cast(gr_context_t*) context.Handle, 262 cast(gr_backendtexture_t*) texture.Handle, origin, sampleCount, ToNative(colorType), 263 cast(sk_colorspace_t*)(colorspace.Handle ? colorspace.Handle : null), 264 cast(sk_surfaceprops_t*)(props.Handle ? props.Handle : null))); 265 } 266 267 // GPU BACKEND TEXTURE AS RENDER TARGET surface 268 269 static SKSurface CreateAsRenderTarget(GRContext context, GRGlBackendTextureDesc desc) { 270 return CreateAsRenderTarget(context, new GRBackendTexture(desc), 271 desc.Origin, desc.SampleCount, desc.Config.ToColorType(), null, null); 272 } 273 274 static SKSurface CreateAsRenderTarget(GRContext context, GRBackendTextureDesc desc) { 275 return CreateAsRenderTarget(context, new GRBackendTexture(desc), 276 desc.Origin, desc.SampleCount, desc.Config.ToColorType(), null, null); 277 } 278 279 static SKSurface CreateAsRenderTarget(GRContext context, 280 GRGlBackendTextureDesc desc, SKSurfaceProps props) { 281 return CreateAsRenderTarget(context, new GRBackendTexture(desc), desc.Origin, 282 desc.SampleCount, desc.Config.ToColorType(), null, new SKSurfaceProperties(props)); 283 } 284 285 static SKSurface CreateAsRenderTarget(GRContext context, 286 GRBackendTextureDesc desc, SKSurfaceProps props) { 287 return CreateAsRenderTarget(context, new GRBackendTexture(desc), desc.Origin, 288 desc.SampleCount, desc.Config.ToColorType(), null, new SKSurfaceProperties(props)); 289 } 290 291 static SKSurface CreateAsRenderTarget(GRContext context, 292 GRBackendTexture texture, SKColorType colorType) { 293 return CreateAsRenderTarget(context, texture, 294 GRSurfaceOrigin.BottomLeft, 0, colorType, null, null); 295 } 296 297 static SKSurface CreateAsRenderTarget(GRContext context, 298 GRBackendTexture texture, GRSurfaceOrigin origin, SKColorType colorType) { 299 return CreateAsRenderTarget(context, texture, origin, 0, colorType, null, null); 300 } 301 302 static SKSurface CreateAsRenderTarget(GRContext context, GRBackendTexture texture, 303 GRSurfaceOrigin origin, int sampleCount, SKColorType colorType) { 304 return CreateAsRenderTarget(context, texture, origin, sampleCount, colorType, null, null); 305 } 306 307 static SKSurface CreateAsRenderTarget(GRContext context, GRBackendTexture texture, 308 GRSurfaceOrigin origin, int sampleCount, SKColorType colorType, SKColorSpace colorspace) { 309 return CreateAsRenderTarget(context, texture, origin, sampleCount, 310 colorType, colorspace, null); 311 } 312 313 static SKSurface CreateAsRenderTarget(GRContext context, 314 GRBackendTexture texture, SKColorType colorType, SKSurfaceProperties props) { 315 return CreateAsRenderTarget(context, texture, 316 GRSurfaceOrigin.BottomLeft, 0, colorType, null, props); 317 } 318 319 static SKSurface CreateAsRenderTarget(GRContext context, GRBackendTexture texture, 320 GRSurfaceOrigin origin, SKColorType colorType, SKSurfaceProperties props) { 321 return CreateAsRenderTarget(context, texture, origin, 0, colorType, null, props); 322 } 323 324 static SKSurface CreateAsRenderTarget(GRContext context, GRBackendTexture texture, 325 GRSurfaceOrigin origin, int sampleCount, SKColorType colorType, 326 SKSurfaceProperties props) { 327 return CreateAsRenderTarget(context, texture, origin, sampleCount, colorType, null, props); 328 } 329 330 static SKSurface CreateAsRenderTarget(GRContext context, GRBackendTexture texture, GRSurfaceOrigin origin, 331 int sampleCount, SKColorType colorType, SKColorSpace colorspace, 332 SKSurfaceProperties props) { 333 if (context is null) 334 throw new ArgumentNullException(context.stringof); 335 if (texture is null) 336 throw new ArgumentNullException(texture.stringof); 337 338 return GetObject(SkiaApi.sk_surface_new_backend_texture_as_render_target(cast(gr_context_t*) context.Handle, 339 cast(gr_backendtexture_t*) texture.Handle, origin, sampleCount, ToNative(colorType), 340 cast(sk_colorspace_t*)(colorspace.Handle ? colorspace.Handle : null), 341 cast(sk_surfaceprops_t*)(props.Handle ? props.Handle : null))); 342 } 343 344 // GPU NEW surface 345 346 static SKSurface Create(GRContext context, bool budgeted, SKImageInfo info, 347 int sampleCount, SKSurfaceProps props) { 348 return Create(context, budgeted, info, sampleCount, 349 GRSurfaceOrigin.BottomLeft, new SKSurfaceProperties(props), false); 350 } 351 352 static SKSurface Create(GRContext context, bool budgeted, SKImageInfo info) { 353 return Create(context, budgeted, info, 0, GRSurfaceOrigin.BottomLeft, null, false); 354 } 355 356 static SKSurface Create(GRContext context, bool budgeted, SKImageInfo info, int sampleCount) { 357 return Create(context, budgeted, info, sampleCount, 358 GRSurfaceOrigin.BottomLeft, null, false); 359 } 360 361 static SKSurface Create(GRContext context, bool budgeted, SKImageInfo info, 362 int sampleCount, GRSurfaceOrigin origin) { 363 return Create(context, budgeted, info, sampleCount, origin, null, false); 364 } 365 366 static SKSurface Create(GRContext context, bool budgeted, SKImageInfo info, 367 SKSurfaceProperties props) { 368 return Create(context, budgeted, info, 0, GRSurfaceOrigin.BottomLeft, props, false); 369 } 370 371 static SKSurface Create(GRContext context, bool budgeted, SKImageInfo info, 372 int sampleCount, SKSurfaceProperties props) { 373 return Create(context, budgeted, info, sampleCount, 374 GRSurfaceOrigin.BottomLeft, props, false); 375 } 376 377 static SKSurface Create(GRContext context, bool budgeted, SKImageInfo info, int sampleCount, 378 GRSurfaceOrigin origin, SKSurfaceProperties props, bool shouldCreateWithMips) { 379 if (context is null) 380 throw new ArgumentNullException(context.stringof); 381 382 auto cinfo = SKImageInfo.FromManaged(info); 383 return GetObject(SkiaApi.sk_surface_new_render_target(cast(gr_context_t*) context.Handle, budgeted, 384 &cinfo, sampleCount, origin, cast(sk_surfaceprops_t*)(props.Handle 385 ? props.Handle : null), shouldCreateWithMips)); 386 } 387 388 // NULL surface 389 390 static SKSurface CreateNull(int width, int height) { 391 return GetObject(SkiaApi.sk_surface_new_null(width, height)); 392 } 393 394 // 395 396 SKCanvas Canvas() { 397 return OwnedBy(SKCanvas.GetObject(SkiaApi.sk_surface_get_canvas(cast(sk_surface_t*) Handle), 398 false, false), this); 399 } 400 401 SKSurfaceProps SurfaceProps() { 402 auto props = SurfaceProperties; 403 SKSurfaceProps surfaceProps = SKSurfaceProps(); 404 surfaceProps.Flags = props.Flags; 405 surfaceProps.PixelGeometry = props.PixelGeometry; 406 return surfaceProps; 407 } 408 409 SKSurfaceProperties SurfaceProperties() { 410 return OwnedBy(SKSurfaceProperties.GetObject(cast( 411 void*) SkiaApi.sk_surface_get_props(cast(sk_surface_t*) Handle), false), this); 412 } 413 414 SKImage Snapshot() { 415 return SKImage.GetObject(SkiaApi.sk_surface_new_image_snapshot(cast(sk_surface_t*) Handle)); 416 } 417 418 SKImage Snapshot(SKRectI bounds) { 419 return SKImage.GetObject(SkiaApi.sk_surface_new_image_snapshot_with_crop( 420 cast(sk_surface_t*) Handle, &bounds)); 421 } 422 423 void Draw(SKCanvas canvas, float x, float y, SKPaint paint) { 424 if (canvas is null) 425 throw new ArgumentNullException(canvas.stringof); 426 427 SkiaApi.sk_surface_draw(cast(sk_surface_t*) Handle, 428 cast(sk_canvas_t*) canvas.Handle, x, y, 429 cast(sk_paint_t*)(paint is null ? null : paint.Handle)); 430 } 431 432 SKPixmap PeekPixels() { 433 auto pixmap = new SKPixmap(); 434 auto result = PeekPixels(pixmap); 435 if (result) { 436 return pixmap; 437 } else { 438 pixmap.Dispose(); 439 return null; 440 } 441 } 442 443 bool PeekPixels(SKPixmap pixmap) { 444 if (pixmap is null) 445 throw new ArgumentNullException(pixmap.stringof); 446 447 auto result = SkiaApi.sk_surface_peek_pixels(cast(sk_surface_t*) Handle, 448 cast(sk_pixmap_t*) pixmap.Handle); 449 if (result) 450 pixmap.pixelSource = this; 451 return result; 452 } 453 454 bool ReadPixels(SKImageInfo dstInfo, void* dstPixels, int dstRowBytes, int srcX, int srcY) { 455 auto cinfo = SKImageInfo.FromManaged(dstInfo); 456 auto result = SkiaApi.sk_surface_read_pixels(cast(sk_surface_t*) Handle, 457 &cinfo, cast(void*) dstPixels, cast(void*) dstRowBytes, srcX, srcY); 458 // GC.KeepAlive (this); 459 return result; 460 } 461 462 static SKSurface GetObject(void* handle) { 463 return handle is null ? null : new SKSurface(handle, true); 464 } 465 466 }