Пример #1
0
// GetSnapshotCustom runs asynchronously, taking a snapshot of the WebView.
// Upon completion, resultCallback will be called with a copy of the underlying
// bitmap backing store for the frame, or with an error encountered during
// execution.
//
// See also: webkit_web_view_get_snapshot at
// http://webkitgtk.org/reference/webkit2gtk/stable/WebKitWebView.html#webkit-web-view-get-snapshot
func (v *WebView) GetSnapshotCustom(region SnapshotRegion, options SnapshotOptions, resultCallback func(result *image.RGBA, err error)) {
	var cCallback C.GAsyncReadyCallback
	var userData C.gpointer
	var err error
	if resultCallback != nil {
		callback := func(result *C.GAsyncResult) {
			var snapErr *C.GError
			snapResult := C.webkit_web_view_get_snapshot_finish(v.webView, result, &snapErr)
			if snapResult == nil {
				defer C.g_error_free(snapErr)
				msg := C.GoString((*C.char)(snapErr.message))
				resultCallback(nil, errors.New(msg))
				return
			}
			defer C.cairo_surface_destroy(snapResult)

			if C.cairo_surface_get_type(snapResult) != cairoSurfaceTypeImage ||
				C.cairo_image_surface_get_format(snapResult) != cairoImageSurfaceFormatARGB32 {
				panic("Snapshot in unexpected format")
			}

			w := int(C.cairo_image_surface_get_width(snapResult))
			h := int(C.cairo_image_surface_get_height(snapResult))
			stride := int(C.cairo_image_surface_get_stride(snapResult))
			C.cairo_surface_flush(snapResult)
			data := unsafe.Pointer(C.cairo_image_surface_get_data(snapResult))

			//(miha) fix endianes depended byte order, and copy to go slice at the same time.
			data_fixed := make([]byte, stride*h)
			C.gowk2_cairo_endian_depended_ARGB32_to_RGBA((*C.uchar)(data), (*C.uchar)(&data_fixed[0]), C.uint(stride*h))
			rgba := &image.RGBA{data_fixed, stride, image.Rect(0, 0, w, h)}

			// slower but doesn't use Go pointers inside C. See https://github.com/golang/go/issues/8310 !!!!!!!
			//C.gowk2_cairo_endian_depended_ARGB32_to_RGBA((*C.uchar)(data), C.uint(stride*h))
			//rgba := &image.RGBA{C.GoBytes(data, C.int(stride*h)), stride, image.Rect(0, 0, w, h)}

			resultCallback(rgba, nil)
		}
		cCallback, userData, err = newGAsyncReadyCallback(callback)
		if err != nil {
			panic(err)
		}
	}

	C.webkit_web_view_get_snapshot(v.webView,
		(C.WebKitSnapshotRegion)(region),
		(C.WebKitSnapshotOptions)(options),
		nil,
		cCallback,
		userData)
}
Пример #2
0
// GetSnapshot runs asynchronously, taking a snapshot of the WebView.
// Upon completion, resultCallback will be called with a copy of the underlying
// bitmap backing store for the frame, or with an error encountered during
// execution.
//
// See also: webkit_web_view_get_snapshot at
// http://webkitgtk.org/reference/webkit2gtk/stable/WebKitWebView.html#webkit-web-view-get-snapshot
func (v *WebView) GetSnapshot(resultCallback func(result *image.RGBA, err error)) {
	var cCallback C.GAsyncReadyCallback
	var userData C.gpointer
	var err error
	if resultCallback != nil {
		callback := func(result *C.GAsyncResult) {
			var snapErr *C.GError
			snapResult := C.webkit_web_view_get_snapshot_finish(v.webView, result, &snapErr)
			if snapResult == nil {
				defer C.g_error_free(snapErr)
				msg := C.GoString((*C.char)(snapErr.message))
				resultCallback(nil, errors.New(msg))
				return
			}
			defer C.cairo_surface_destroy(snapResult)

			if C.cairo_surface_get_type(snapResult) != cairoSurfaceTypeImage ||
				C.cairo_image_surface_get_format(snapResult) != cairoImageSurfaceFormatARB32 {
				panic("Snapshot in unexpected format")
			}

			w := int(C.cairo_image_surface_get_width(snapResult))
			h := int(C.cairo_image_surface_get_height(snapResult))
			stride := int(C.cairo_image_surface_get_stride(snapResult))
			data := unsafe.Pointer(C.cairo_image_surface_get_data(snapResult))
			rgba := &image.RGBA{C.GoBytes(data, C.int(stride*h)), stride, image.Rect(0, 0, w, h)}
			resultCallback(rgba, nil)
		}
		cCallback, userData, err = newGAsyncReadyCallback(callback)
		if err != nil {
			panic(err)
		}
	}

	C.webkit_web_view_get_snapshot(v.webView,
		(C.WebKitSnapshotRegion)(1), // FullDocument is the only working region at this point
		(C.WebKitSnapshotOptions)(0),
		nil,
		cCallback,
		userData)
}
Пример #3
0
//XtensionRevivifySurface recreates a Go Surface of the proper type
//from a C surface.
//
//This is for extension writers only.
func XtensionRevivifySurface(s *C.cairo_surface_t) (S Surface, err error) {
	t := surfaceType(C.cairo_surface_get_type(s))
	f, ok := csurftogosurf[t]
	if !ok {
		panic("No C → Go surface converter registered for " + t.String())
	}
	S, err = f(s)
	if err != nil {
		return nil, err
	}
	if t == SurfaceTypeImage {
		mismux.Lock()
		defer mismux.Unlock()
		if _, ok := mis[surfaceGetID(s)]; ok {
			S = toMapped(S.(ImageSurface))
		}
	}
	if err = S.Err(); err != nil {
		return nil, err
	}
	return S, nil
}
Пример #4
0
func (self *Surface) GetType() SurfaceType {
	return SurfaceType(C.cairo_surface_get_type(self.surface))
}
Пример #5
0
// GetType is a wrapper around cairo_surface_get_type().
func (v *Surface) GetType() SurfaceType {
	c := C.cairo_surface_get_type(v.native())
	return SurfaceType(c)
}
Пример #6
0
//Type reports the type of this surface.
//
//Originally cairo_surface_get_type.
func (e *XtensionSurface) Type() surfaceType {
	return surfaceType(C.cairo_surface_get_type(e.s))
}
Пример #7
0
// GetSnapshot runs asynchronously, taking a snapshot of the WebView.
// Upon completion, resultCallback will be called with a copy of the underlying
// bitmap backing store for the frame, or with an error encountered during
// execution.
//
// See also: webkit_web_view_get_snapshot at
// http://webkitgtk.org/reference/webkit2gtk/stable/WebKitWebView.html#webkit-web-view-get-snapshot
func (v *WebView) GetSnapshot(resultCallback func(result *image.RGBA, err error)) {
	var cCallback C.GAsyncReadyCallback
	var userData C.gpointer
	var err error
	if resultCallback != nil {
		callback := func(result *C.GAsyncResult) {
			var snapErr *C.GError
			snapResult := C.webkit_web_view_get_snapshot_finish(v.webView, result, &snapErr)
			if snapResult == nil {
				defer C.g_error_free(snapErr)
				msg := C.GoString((*C.char)(snapErr.message))
				resultCallback(nil, errors.New(msg))
				return
			}
			defer C.cairo_surface_destroy(snapResult)

			if C.cairo_surface_get_type(snapResult) != cairoSurfaceTypeImage ||
				C.cairo_image_surface_get_format(snapResult) != cairoImageSurfaceFormatARGB32 {
				panic("Snapshot in unexpected format")
			}

			w := int(C.cairo_image_surface_get_width(snapResult))
			h := int(C.cairo_image_surface_get_height(snapResult))
			stride := int(C.cairo_image_surface_get_stride(snapResult))
			data := unsafe.Pointer(C.cairo_image_surface_get_data(snapResult))
			surfaceBytes := C.GoBytes(data, C.int(stride*h))
			// convert from b,g,r,a or a,r,g,b(local endianness) to r,g,b,a
			testint, _ := binary.ReadUvarint(bytes.NewBuffer([]byte{0x1, 0}))
			if testint == 0x1 {
				// Little: b,g,r,a -> r,g,b,a
				for i := 0; i < w*h; i++ {
					b := surfaceBytes[4*i+0]
					r := surfaceBytes[4*i+2]
					surfaceBytes[4*i+0] = r
					surfaceBytes[4*i+2] = b
				}
			} else {
				// Big: a,r,g,b -> r,g,b,a
				for i := 0; i < w*h; i++ {
					a := surfaceBytes[4*i+0]
					r := surfaceBytes[4*i+1]
					g := surfaceBytes[4*i+2]
					b := surfaceBytes[4*i+3]
					surfaceBytes[4*i+0] = r
					surfaceBytes[4*i+1] = g
					surfaceBytes[4*i+2] = b
					surfaceBytes[4*i+3] = a
				}
			}
			rgba := &image.RGBA{surfaceBytes, stride, image.Rect(0, 0, w, h)}
			resultCallback(rgba, nil)
		}
		cCallback, userData, err = newGAsyncReadyCallback(callback)
		if err != nil {
			panic(err)
		}
	}

	C.webkit_web_view_get_snapshot(v.webView,
		(C.WebKitSnapshotRegion)(1), // FullDocument is the only working region at this point
		(C.WebKitSnapshotOptions)(0),
		nil,
		cCallback,
		userData)
}
Пример #8
0
//export go_genericGAsyncCallback
func go_genericGAsyncCallback(source *C.GObject, result *C.GAsyncResult, callbackId *C.char) {
	key := C.GoString(callbackId)

	if obj, ok := cgoget(key); ok {
		switch obj.(type) {
		case *RunJavaScriptResponse:
			var jserr *C.GError

			response := obj.(*RunJavaScriptResponse)

			if response.Autoremove {
				defer cgounregister(key)
			}

			if jsResult := C.webkit_web_view_run_javascript_finish(response.CWebView, result, &jserr); jsResult == nil {
				defer C.g_error_free(jserr)
				msg := C.GoString((*C.char)(jserr.message))
				response.Reply(nil, errors.New(msg))
			} else {
				ctxRaw := gojs.RawGlobalContext(unsafe.Pointer(C.webkit_javascript_result_get_global_context(jsResult)))
				jsValRaw := gojs.RawValue(unsafe.Pointer(C.webkit_javascript_result_get_value(jsResult)))
				ctx := (*gojs.Context)(gojs.NewGlobalContextFrom(ctxRaw))
				jsVal := ctx.NewValueFrom(jsValRaw)
				response.Reply(jsVal, nil)
			}

		case *GetSnapshotAsImageResponse:
			var snapErr *C.GError

			response := obj.(*GetSnapshotAsImageResponse)

			if response.Autoremove {
				defer cgounregister(key)
			}

			if snapResult := C.webkit_web_view_get_snapshot_finish(response.CWebView, result, &snapErr); snapResult == nil {
				defer C.g_error_free(snapErr)
				msg := C.GoString((*C.char)(snapErr.message))
				response.Reply(nil, errors.New(msg))
			} else {
				defer C.cairo_surface_destroy(snapResult)

				if C.cairo_surface_get_type(snapResult) != cairoSurfaceTypeImage ||
					C.cairo_image_surface_get_format(snapResult) != cairoImageSurfaceFormatARGB32 {
					response.Reply(nil, errors.New("Snapshot in unexpected format"))
					return
				}

				w := int(C.cairo_image_surface_get_width(snapResult))
				h := int(C.cairo_image_surface_get_height(snapResult))
				stride := int(C.cairo_image_surface_get_stride(snapResult))
				data := unsafe.Pointer(C.cairo_image_surface_get_data(snapResult))
				surfaceBytes := C.GoBytes(data, C.int(stride*h))

				// convert from b,g,r,a or a,r,g,b(local endianness) to r,g,b,a
				testint, _ := binary.ReadUvarint(bytes.NewBuffer([]byte{0x1, 0}))

				if testint == 0x1 {
					// Little: b,g,r,a -> r,g,b,a
					for i := 0; i < w*h; i++ {
						b := surfaceBytes[4*i+0]
						r := surfaceBytes[4*i+2]
						surfaceBytes[4*i+0] = r
						surfaceBytes[4*i+2] = b
					}
				} else {
					// Big: a,r,g,b -> r,g,b,a
					for i := 0; i < w*h; i++ {
						a := surfaceBytes[4*i+0]
						r := surfaceBytes[4*i+1]
						g := surfaceBytes[4*i+2]
						b := surfaceBytes[4*i+3]
						surfaceBytes[4*i+0] = r
						surfaceBytes[4*i+1] = g
						surfaceBytes[4*i+2] = b
						surfaceBytes[4*i+3] = a
					}
				}

				rgba := &image.RGBA{
					Pix:    surfaceBytes,
					Stride: stride,
					Rect:   image.Rect(0, 0, w, h),
				}

				response.Reply(rgba, nil)
			}

		case *GetSnapshotAsCairoSurfaceResponse:
			var snapErr *C.GError

			response := obj.(*GetSnapshotAsCairoSurfaceResponse)

			snapResult := C.webkit_web_view_get_snapshot_finish(response.CWebView, result, &snapErr)

			if snapResult == nil {
				defer C.g_error_free(snapErr)
				msg := C.GoString((*C.char)(snapErr.message))
				response.Reply(nil, errors.New(msg))
			} else {
				surface := cairo.NewSurface(uintptr(unsafe.Pointer(snapResult)), false)

				if status := surface.Status(); status == cairo.STATUS_SUCCESS {
					response.Reply(surface, nil)
				} else {
					response.Reply(nil, fmt.Errorf("Cairo surface error %d", status))
				}
			}
		}
	}
}