fontina-windows 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 475183ef6216f5b7b1f72b687c2f026965f9fb80
4
- data.tar.gz: 2f7e6de102596e7bffe1490d62e0c6195990e06b
3
+ metadata.gz: 55d03dfce54c89c35f52e503d565660046c4b671
4
+ data.tar.gz: 6ab00ce95e2af9ea45be31b0b57f41e6ae815881
5
5
  SHA512:
6
- metadata.gz: 7246fcbec02d446b3b98a73aacf34b8d7f7e83ee4588d11d6cbe30fc50289281fd03be88f35c5d0704f454708a9978c8a0f08e29abd49d5d7ec82ce113404dff
7
- data.tar.gz: 9af0184ecfe4375d2756c080b3fc8707d38b1cd973c83867c430eb4ac18d57dbd899b904b25025f0167d2f537511a392763285646783310074362d86154f4c98
6
+ metadata.gz: 2fd9d079d5086fdc370994f61545c9ae6f2390efb2202c7c3266711f5da0205a08d706b65d931a5e8132bccc95e9bf0741bb1f0e552b6160a45e2d3217b59aef
7
+ data.tar.gz: 45dab25148741f87fefe7ebaf7ceb7276cd1d9f2f80cd79510900f78263aecaea9d5f4d5a9ce116bc51c6067ae156160bdc3a32b44bfeff691915a382cf323a6
@@ -18,7 +18,7 @@ Gem::Specification.new do |gem|
18
18
  gem.require_paths = ['lib']
19
19
 
20
20
  gem.add_dependency 'fontina', '>= 0.2.1'
21
- gem.add_dependency 'mores', '>= 0.1.5'
21
+ gem.add_dependency 'mores', '>= 0.3.1'
22
22
 
23
23
  gem.add_development_dependency 'bundler', '~> 1.7'
24
24
  gem.add_development_dependency 'rake', '~> 10.0'
@@ -5,6 +5,8 @@ module Fontina
5
5
  include Marshal
6
6
  Fontina::MetaPackage.include self
7
7
 
8
+ using Mores::Patch::FileUtils
9
+
8
10
  def registered_name
9
11
  @registered_name ||= begin
10
12
  name = package.preferred_name \
@@ -17,18 +19,32 @@ module Fontina
17
19
  end
18
20
  end
19
21
 
20
- def install
21
- conflicts = Windows.registered_fonts
22
- .find_all { |(name, path)| (name == registered_name) ^ (path == file.filename) }
23
- fail "Conflicting registrations found: #{conflicts.to_h}" unless conflicts.empty?
22
+ def installed?
23
+ !!(path = Windows.font_registered? registered_name) and
24
+ path = File.expand_path(path, Windows.fonts_directory) and
25
+ File.file?(path) and
26
+ File.open(path) { |io| FileUtils.compare_stream io.binmode, StringIO.new(file.content) }
27
+ end
28
+
29
+ def install(force: false)
30
+ return if installed? unless force
24
31
 
25
- File.write File.join(Windows.fonts_directory, file.filename), file.content
32
+ add_times = 1
33
+ path = Windows.font_registered? registered_name
34
+
35
+ Dir.chdir(Windows.fonts_directory) do
36
+ add_times = Windows.remove_font_resource path if path and File.exist? path
37
+ path, = FileUtils.safe_write file.filename, file.content
38
+ end
26
39
 
27
- unless (count = Windows.add_font_resource file.filename) == package.fonts.length
28
- fail "Windows reported #{count} fonts added (expected: #{package.fonts.length})"
40
+ Windows.add_font_resource(path, times: add_times).tap do |count|
41
+ unless count == package.fonts.length
42
+ fail "Windows reported #{count} fonts added (expected: #{package.fonts.length})"
43
+ end
29
44
  end
30
45
 
31
- Windows.register_font registered_name, file.filename
46
+ Windows.register_font registered_name, path
47
+ Windows.notify_fonts_changed
32
48
  end
33
49
  end
34
50
 
@@ -1,7 +1,7 @@
1
1
  module Fontina
2
2
 
3
3
  module Windows
4
- VERSION = '0.1.0'
4
+ VERSION = '0.2.0'
5
5
  end
6
6
 
7
7
  end
@@ -48,7 +48,7 @@ module Fontina::Windows::Win32
48
48
  )
49
49
 
50
50
  extern 'long RegGetValueW(PVOID, LPCSTR, LPCSTR, DWORD, DWORD*, BYTE*, DWORD*)' \
51
- do |hkey, subkey, name, flags: RRF_RT_ANY, data_len: nil|
51
+ do |hkey, name, subkey: nil, flags: RRF_RT_ANY, data_len: nil|
52
52
  type = dword(NULL)
53
53
  data, data_len = data_len ? [byte(0) * data_len, dword(data_len)] : [NULL, dword(NULL)]
54
54
  Error.check super(hkey, wstr(subkey), wstr(name), flags, type, data, data_len)
@@ -3,9 +3,10 @@ module Fontina::Windows::Win32
3
3
  NULL = 0
4
4
  MAX_PATH = 260
5
5
 
6
- ERROR_SUCCESS = 0
7
- ERROR_MORE_DATA = 234
8
- ERROR_NO_MORE_ITEMS = 259
6
+ ERROR_SUCCESS = 0
7
+ ERROR_FILE_NOT_FOUND = 2
8
+ ERROR_MORE_DATA = 234
9
+ ERROR_NO_MORE_ITEMS = 259
9
10
 
10
11
  FORMAT_MESSAGE_FROM_SYSTEM = 0x1000
11
12
  FORMAT_MESSAGE_IGNORE_INSERTS = 0x0200
@@ -31,6 +31,10 @@ module Fontina::Windows::Win32
31
31
  def check_hr(code)
32
32
  raise new code unless 0 == code[31]
33
33
  end
34
+
35
+ def clear
36
+ Kernel32.SetLastError(ERROR_SUCCESS)
37
+ end
34
38
  end
35
39
  end
36
40
 
@@ -7,6 +7,14 @@ module Fontina::Windows::Win32
7
7
  Error.check_last if 0 == count
8
8
  count
9
9
  end
10
+
11
+ extern 'BOOL RemoveFontResourceW(LPCSTR)' \
12
+ do |filename|
13
+ Error.clear
14
+ success = 0 != super(wstr filename)
15
+ Error.check_last unless success
16
+ success
17
+ end
10
18
  end
11
19
 
12
20
  end
@@ -2,6 +2,7 @@ module Fontina::Windows::Win32
2
2
 
3
3
  dlload :Kernel32 do
4
4
  extern 'DWORD GetLastError()'
5
+ extern 'void SetLastError(DWORD)'
5
6
 
6
7
  extern 'DWORD FormatMessageW(DWORD, PVOID, DWORD, DWORD, LPSTR, DWORD, PVOID)' \
7
8
  do |flags, message_id, len, source: NULL, language_id: 0|
@@ -1,32 +1,34 @@
1
1
  %w[
2
2
  fontina
3
+ fontina/windows/language_codes
3
4
  fiddle
5
+ fiddle/import
4
6
  fiddle/types
5
7
  ].each { |lib| require lib }
6
8
 
7
9
  %w[
8
10
  version
9
- language_codes
10
11
  marshal
11
12
  win32
12
13
  package
13
14
  meta_package
14
15
  install
15
- ].each { |file| require "fontina/windows/#{file}" }
16
+ ].each { |file| require_relative "windows/#{file}" }
16
17
 
17
18
  module Fontina::Windows
18
19
  include Win32
19
20
  extend Marshal
21
+ module_function
20
22
 
21
- def self.system_language
23
+ def system_language
22
24
  @system_language ||= LANGUAGE_CODES.fetch Kernel32.GetSystemDefaultUILanguage()
23
25
  end
24
26
 
25
- def self.fonts_directory
27
+ def fonts_directory
26
28
  @fonts_directory ||= Shell32.SHGetFolderPathW(CSIDL_FONTS).encode('filesystem').freeze
27
29
  end
28
30
 
29
- def self.registered_fonts
31
+ def registered_fonts
30
32
  key = Advapi32.RegOpenKeyExW(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts', KEY_READ)
31
33
  begin
32
34
  Advapi32.RegQueryInfoKeyW(key)
@@ -43,13 +45,21 @@ module Fontina::Windows
43
45
  end
44
46
  end
45
47
 
46
- def self.add_font_resource(path)
47
- Gdi32.AddFontResourceW(path).tap do |count|
48
- User32.PostMessageW(HWND_BROADCAST, WM_FONTCHANGE, 0, 0) if 0 < count
48
+ def font_registered?(name)
49
+ key = Advapi32.RegOpenKeyExW(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts', KEY_READ)
50
+ begin
51
+ Advapi32.RegGetValueW(key, name, flags: RRF_RT_REG_SZ).tap do |value|
52
+ value = Advapi32.RegGetValueW(key, name, data_len: value.data_len)
53
+ break wstr!(value.data).rstrip.encode('filesystem')
54
+ end
55
+ rescue Error => e
56
+ raise if e.code != ERROR_FILE_NOT_FOUND
57
+ ensure
58
+ Advapi32.RegCloseKey(key)
49
59
  end
50
60
  end
51
61
 
52
- def self.register_font(name, path)
62
+ def register_font(name, path)
53
63
  key = Advapi32.RegOpenKeyExW(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts', KEY_WRITE)
54
64
  begin
55
65
  Advapi32.RegSetValueExW(key, name, REG_SZ, wstr(path) + wchar(0))
@@ -58,4 +68,16 @@ module Fontina::Windows
58
68
  end
59
69
  end
60
70
 
71
+ def add_font_resource(path, times: 1)
72
+ (1..times).reduce(nil) { Gdi32.AddFontResourceW(path) }
73
+ end
74
+
75
+ def remove_font_resource(path)
76
+ (0..Float::INFINITY).find { !Gdi32.RemoveFontResourceW(path) }
77
+ end
78
+
79
+ def notify_fonts_changed
80
+ User32.PostMessageW(HWND_BROADCAST, WM_FONTCHANGE, 0, 0)
81
+ end
82
+
61
83
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fontina-windows
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Petter
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-02-17 00:00:00.000000000 Z
11
+ date: 2017-02-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fontina
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 0.1.5
33
+ version: 0.3.1
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: 0.1.5
40
+ version: 0.3.1
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: bundler
43
43
  requirement: !ruby/object:Gem::Requirement