So I tried to get a little creative this time around and use something other than Arial as my default font in my Title Block tool (which uses the add_3d_text method) that is part of my Medeek Project extension:
It worked great on my system (I have Microsoft Word installed), and of course failed miserably on anyone who did not have this font installed.
The slightly annoying thing is that SketchUp’s error doesn’t really tell you that the font is the issue, it just fails to create the 3D text.
Rather than hard code in a select few fonts that I know everyone should have I think it would be better to have my plugin code determine what is available on the users system and then provide those as options. Obviously not all fonts work with this method, so it may be more complicated than just enumerating all the installed fonts on a Mac or PC.
How would I go about doing that? Does anyone have any experience with doing this sort of thing?
Note how it uses some constants like FOLDER and NAME which you’ll need to adjust for your set up…
This example is looking for a font name “Txt”, with a file-name of “txt_____.ttf”, shipped with this particular custom extension, and which the user needs to install first off…
It also defaults to “Arial” if the specified font is not found, so you probably want to adjust these too…
If works for PC & MAC, a MAC will crash if the font is missing, a PC will simple do nothing at all !
### Font check
@@font = "Txt"
@@fontname = "txt_____.ttf"
@@txtfont = File.join(FOLDER, @@fontname)
if RUBY_PLATFORM.downcase =~ /mswin|mingw/ ### pc
find = false
Dir.entries("C:/Windows/Fonts").grep(/ttf$/).grep(/^txt/).each{|e|
if e =~ /^txt_/
find = true
break
end
}
if find
#UI.messagebox("#{NAME}:\n\n'#{@@font}' font installed.")
else ### missing
UI.messagebox("#{NAME}:\n\n'#{@@font}' font is NOT installed.\nWithout it References will be in 'Arial' font.\nInstall it and restart.\nIf you do not have permission, get an 'Admin' to install it from:\n#{@@txtfont}")
@@font = "Arial"
end
else ### mac
if find = %x(mdfind -onlyin ~/Library/Fonts 'kMDItemKind == "TrueType font" && kMDItemDisplayName == "#{@@fontname}"')
elsif find = %x(mdfind -onlyin /Library/Fonts 'kMDItemKind == "TrueType font" && kMDItemDisplayName == "#{@@fontname}"')
elsif find = %x(mdfind -onlyin /Network/Library/Fonts 'kMDItemKind == "TrueType font" && kMDItemDisplayName == "#{@@fontname}"')
elsif find = %x(mdfind -onlyin /System/Library/Fonts 'kMDItemKind == "TrueType font" && kMDItemDisplayName == "#{@@fontname}"')
elsif find = %x(mdfind -onlyin /System Folder/Library/Fonts 'kMDItemKind == "TrueType font" && kMDItemDisplayName == "#{@@fontname}"')
else
find=false
end
if find && !find.empty?
#UI.messagebox("#{@@font} font exists #{find}.")
else
UI.messagebox("#{NAME}:\n\n'#{@@font}' font is NOT installed.\nWithout it References will be in 'Arial' font.\nInstall it and restart.\nIf you do not have permission, get an 'Admin' to install it from:\n#{@@txtfont}")
@@font = "Arial"
end
end
Actually an easier way would be to use a backtick (aka%x) string to use Windows’ reg.exe command line utility.
def get_fonts # MS Windows
fonts = []
Dir.chdir(__dir__) do |path|
%x[reg export "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts" "fonts.txt" /y]
sleep 0.5
lines = File.readlines(
'fonts.txt', chomp: true, encoding: 'UTF-16LE:UTF-8'
)
lines.each { |line|
next unless line.start_with?('"')
font = line.split('"=').first
font.delete_prefix!('"')
font.delete_suffix!(' (TrueType)')
fonts << font
}
puts "Fonts names retrieved: #{fonts.size}"
nil
end
return fonts
end
The reg.exe utility exports in .reg format which is importable back in any windows registry. So I force a .txt extension. Also it writes in UTF-16 Little Endian w/ Bit Order Mark encoding, so we must make sure to use this external encoding for IO methods.