github.com/secoba/wails/v2@v2.6.4/internal/frontend/desktop/windows/winc/w32/gdiplus.go (about)

     1  //go:build windows
     2  
     3  /*
     4   * Copyright (C) 2019 The Winc Authors. All Rights Reserved.
     5   * Copyright (C) 2010-2012 The W32 Authors. All Rights Reserved.
     6   */
     7  package w32
     8  
     9  import (
    10  	"errors"
    11  	"fmt"
    12  	"syscall"
    13  	"unsafe"
    14  )
    15  
    16  const (
    17  	Ok                        = 0
    18  	GenericError              = 1
    19  	InvalidParameter          = 2
    20  	OutOfMemory               = 3
    21  	ObjectBusy                = 4
    22  	InsufficientBuffer        = 5
    23  	NotImplemented            = 6
    24  	Win32Error                = 7
    25  	WrongState                = 8
    26  	Aborted                   = 9
    27  	FileNotFound              = 10
    28  	ValueOverflow             = 11
    29  	AccessDenied              = 12
    30  	UnknownImageFormat        = 13
    31  	FontFamilyNotFound        = 14
    32  	FontStyleNotFound         = 15
    33  	NotTrueTypeFont           = 16
    34  	UnsupportedGdiplusVersion = 17
    35  	GdiplusNotInitialized     = 18
    36  	PropertyNotFound          = 19
    37  	PropertyNotSupported      = 20
    38  	ProfileNotFound           = 21
    39  )
    40  
    41  func GetGpStatus(s int32) string {
    42  	switch s {
    43  	case Ok:
    44  		return "Ok"
    45  	case GenericError:
    46  		return "GenericError"
    47  	case InvalidParameter:
    48  		return "InvalidParameter"
    49  	case OutOfMemory:
    50  		return "OutOfMemory"
    51  	case ObjectBusy:
    52  		return "ObjectBusy"
    53  	case InsufficientBuffer:
    54  		return "InsufficientBuffer"
    55  	case NotImplemented:
    56  		return "NotImplemented"
    57  	case Win32Error:
    58  		return "Win32Error"
    59  	case WrongState:
    60  		return "WrongState"
    61  	case Aborted:
    62  		return "Aborted"
    63  	case FileNotFound:
    64  		return "FileNotFound"
    65  	case ValueOverflow:
    66  		return "ValueOverflow"
    67  	case AccessDenied:
    68  		return "AccessDenied"
    69  	case UnknownImageFormat:
    70  		return "UnknownImageFormat"
    71  	case FontFamilyNotFound:
    72  		return "FontFamilyNotFound"
    73  	case FontStyleNotFound:
    74  		return "FontStyleNotFound"
    75  	case NotTrueTypeFont:
    76  		return "NotTrueTypeFont"
    77  	case UnsupportedGdiplusVersion:
    78  		return "UnsupportedGdiplusVersion"
    79  	case GdiplusNotInitialized:
    80  		return "GdiplusNotInitialized"
    81  	case PropertyNotFound:
    82  		return "PropertyNotFound"
    83  	case PropertyNotSupported:
    84  		return "PropertyNotSupported"
    85  	case ProfileNotFound:
    86  		return "ProfileNotFound"
    87  	}
    88  	return "Unknown Status Value"
    89  }
    90  
    91  var (
    92  	token uintptr
    93  
    94  	modgdiplus = syscall.NewLazyDLL("gdiplus.dll")
    95  
    96  	procGdipCreateBitmapFromFile     = modgdiplus.NewProc("GdipCreateBitmapFromFile")
    97  	procGdipCreateBitmapFromHBITMAP  = modgdiplus.NewProc("GdipCreateBitmapFromHBITMAP")
    98  	procGdipCreateHBITMAPFromBitmap  = modgdiplus.NewProc("GdipCreateHBITMAPFromBitmap")
    99  	procGdipCreateBitmapFromResource = modgdiplus.NewProc("GdipCreateBitmapFromResource")
   100  	procGdipCreateBitmapFromStream   = modgdiplus.NewProc("GdipCreateBitmapFromStream")
   101  	procGdipDisposeImage             = modgdiplus.NewProc("GdipDisposeImage")
   102  	procGdiplusShutdown              = modgdiplus.NewProc("GdiplusShutdown")
   103  	procGdiplusStartup               = modgdiplus.NewProc("GdiplusStartup")
   104  )
   105  
   106  func GdipCreateBitmapFromFile(filename string) (*uintptr, error) {
   107  	var bitmap *uintptr
   108  	ret, _, _ := procGdipCreateBitmapFromFile.Call(
   109  		uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(filename))),
   110  		uintptr(unsafe.Pointer(&bitmap)))
   111  
   112  	if ret != Ok {
   113  		return nil, errors.New(fmt.Sprintf("GdipCreateBitmapFromFile failed with status '%s' for file '%s'", GetGpStatus(int32(ret)), filename))
   114  	}
   115  
   116  	return bitmap, nil
   117  }
   118  
   119  func GdipCreateBitmapFromResource(instance HINSTANCE, resId *uint16) (*uintptr, error) {
   120  	var bitmap *uintptr
   121  	ret, _, _ := procGdipCreateBitmapFromResource.Call(
   122  		uintptr(instance),
   123  		uintptr(unsafe.Pointer(resId)),
   124  		uintptr(unsafe.Pointer(&bitmap)))
   125  
   126  	if ret != Ok {
   127  		return nil, errors.New(fmt.Sprintf("GdiCreateBitmapFromResource failed with status '%s'", GetGpStatus(int32(ret))))
   128  	}
   129  
   130  	return bitmap, nil
   131  }
   132  
   133  func GdipCreateBitmapFromStream(stream *IStream) (*uintptr, error) {
   134  	var bitmap *uintptr
   135  	ret, _, _ := procGdipCreateBitmapFromStream.Call(
   136  		uintptr(unsafe.Pointer(stream)),
   137  		uintptr(unsafe.Pointer(&bitmap)))
   138  
   139  	if ret != Ok {
   140  		return nil, errors.New(fmt.Sprintf("GdipCreateBitmapFromStream failed with status '%s'", GetGpStatus(int32(ret))))
   141  	}
   142  
   143  	return bitmap, nil
   144  }
   145  
   146  func GdipCreateHBITMAPFromBitmap(bitmap *uintptr, background uint32) (HBITMAP, error) {
   147  	var hbitmap HBITMAP
   148  	ret, _, _ := procGdipCreateHBITMAPFromBitmap.Call(
   149  		uintptr(unsafe.Pointer(bitmap)),
   150  		uintptr(unsafe.Pointer(&hbitmap)),
   151  		uintptr(background))
   152  
   153  	if ret != Ok {
   154  		return 0, errors.New(fmt.Sprintf("GdipCreateHBITMAPFromBitmap failed with status '%s'", GetGpStatus(int32(ret))))
   155  	}
   156  
   157  	return hbitmap, nil
   158  }
   159  
   160  func GdipDisposeImage(image *uintptr) {
   161  	procGdipDisposeImage.Call(uintptr(unsafe.Pointer(image)))
   162  }
   163  
   164  func GdiplusShutdown() {
   165  	procGdiplusShutdown.Call(token)
   166  }
   167  
   168  func GdiplusStartup(input *GdiplusStartupInput, output *GdiplusStartupOutput) {
   169  	ret, _, _ := procGdiplusStartup.Call(
   170  		uintptr(unsafe.Pointer(&token)),
   171  		uintptr(unsafe.Pointer(input)),
   172  		uintptr(unsafe.Pointer(output)))
   173  
   174  	if ret != Ok {
   175  		panic("GdiplusStartup failed with status " + GetGpStatus(int32(ret)))
   176  	}
   177  }