fontina-windows 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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