/
fontresource.go
88 lines (71 loc) · 2.49 KB
/
fontresource.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
// Copyright 2010 The Walk Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build windows
package winapi
import (
"syscall"
"github.com/Gipcomp/win32/gdi32"
"github.com/Gipcomp/win32/handle"
"github.com/Gipcomp/win32/kernel32"
"github.com/Gipcomp/win32/win"
"github.com/Gipcomp/winapi/errs"
)
// FontMemResource represents a font resource loaded into memory from
// the application's resources.
type FontMemResource struct {
hFontResource handle.HANDLE
}
func newFontMemResource(resourceName *uint16) (*FontMemResource, error) {
hModule := kernel32.HMODULE(kernel32.GetModuleHandle(nil))
if hModule == kernel32.HMODULE(0) {
return nil, errs.LastError("GetModuleHandle")
}
hres := kernel32.FindResource(hModule, resourceName, win.MAKEINTRESOURCE(8) /*RT_FONT*/)
if hres == kernel32.HRSRC(0) {
return nil, errs.LastError("FindResource")
}
size := kernel32.SizeofResource(hModule, hres)
if size == 0 {
return nil, errs.LastError("SizeofResource")
}
hResLoad := kernel32.LoadResource(hModule, hres)
if hResLoad == kernel32.HGLOBAL(0) {
return nil, errs.LastError("LoadResource")
}
ptr := kernel32.LockResource(hResLoad)
if ptr == 0 {
return nil, errs.LastError("LockResource")
}
numFonts := uint32(0)
hFontResource := gdi32.AddFontMemResourceEx(ptr, size, nil, &numFonts)
if hFontResource == handle.HANDLE(0) || numFonts == 0 {
return nil, errs.LastError("AddFontMemResource")
}
return &FontMemResource{hFontResource: hFontResource}, nil
}
// NewFontMemResourceByName function loads a font resource from the executable's resources
// using the resource name.
// The font must be embedded into resources using corresponding operator in the
// application's RC script.
func NewFontMemResourceByName(name string) (*FontMemResource, error) {
lpstr, err := syscall.UTF16PtrFromString(name)
if err != nil {
return nil, err
}
return newFontMemResource(lpstr)
}
// NewFontMemResourceById function loads a font resource from the executable's resources
// using the resource ID.
// The font must be embedded into resources using corresponding operator in the
// application's RC script.
func NewFontMemResourceById(id int) (*FontMemResource, error) {
return newFontMemResource(win.MAKEINTRESOURCE(uintptr(id)))
}
// Dispose removes the font resource from memory
func (fmr *FontMemResource) Dispose() {
if fmr.hFontResource != 0 {
gdi32.RemoveFontMemResourceEx(fmr.hFontResource)
fmr.hFontResource = 0
}
}