summaryrefslogtreecommitdiffstatshomepage
path: root/fontresource.go
blob: 61f903076f687db3e7684db3fa493ac4810da87d (plain) (blame)
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
// 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 walk

import (
	"github.com/lxn/win"
	"syscall"
)

// FontMemResource represents a font resource loaded into memory from 
// the application's resources.
type FontMemResource struct {
	hFontResource win.HANDLE
}

func newFontMemResource(resourceName *uint16) (*FontMemResource, error) {
	hModule := win.HMODULE(win.GetModuleHandle(nil))
	if hModule == win.HMODULE(0) {
		return nil, lastError("GetModuleHandle")
	}
	
	hres := win.FindResource(hModule, resourceName, win.MAKEINTRESOURCE(8) /*RT_FONT*/)
	if hres == win.HRSRC(0) {
		return nil, lastError("FindResource")
	}

	size := win.SizeofResource(hModule, hres)
	if size == 0 {
		return nil, lastError("SizeofResource")
	}

	hResLoad := win.LoadResource(hModule, hres)
	if hResLoad == win.HGLOBAL(0) {
		return nil, lastError("LoadResource")
	}

	ptr := win.LockResource(hResLoad)
	if ptr == 0 {
		return nil, lastError("LockResource")
	}

	numFonts := uint32(0)
	hFontResource := win.AddFontMemResourceEx(ptr, size, nil, &numFonts)

	if hFontResource == win.HANDLE(0) || numFonts == 0 {
		return nil, 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) {
	return newFontMemResource(syscall.StringToUTF16Ptr(name))
}

// 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 {
		win.RemoveFontMemResourceEx(fmr.hFontResource)
		fmr.hFontResource = 0
	}
}