# # tk/font.rb - the class to treat fonts on Ruby/Tk # # by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) # require 'tk' class TkFont include Tk extend TkCore TkCommandNames = ['font'.freeze].freeze Tk_FontID = ["@font".freeze, "00000".taint].freeze Tk_FontNameTBL = TkCore::INTERP.create_table Tk_FontUseTBL = TkCore::INTERP.create_table TkCore::INTERP.init_ip_env{ Tk_FontNameTBL.clear Tk_FontUseTBL.clear } # option_type : default => string OptionType = Hash.new(?s) OptionType['size'] = ?n OptionType['pointadjust'] = ?n OptionType['underline'] = ?b OptionType['overstrike'] = ?b # metric_type : default => num_or_str MetricType = Hash.new(?n) MetricType['fixed'] = ?b # set default font case Tk::TK_VERSION when /^4\.*/ DEFAULT_LATIN_FONT_NAME = 'a14'.freeze DEFAULT_KANJI_FONT_NAME = 'k14'.freeze when /^8\.*/ if JAPANIZED_TK begin fontnames = tk_call('font', 'names') case fontnames when /defaultgui/ # Tcl/Tk-JP for Windows ltn = 'defaultgui' knj = 'defaultgui' when /Mincho:Helvetica-Bold-12/ # Tcl/Tk-JP for UNIX/X ltn, knj = tk_split_simplelist(tk_call('font', 'configure', 'Mincho:Helvetica-Bold-12', '-compound')) else # unknown Tcl/Tk-JP #platform = tk_call('set', 'tcl_platform(platform)') platform = Tk::PLATFORM['platform'] case platform when 'unix' ltn = {'family'=>'Helvetica'.freeze, 'size'=>-12, 'weight'=>'bold'.freeze} #knj = 'k14' #knj = '-misc-fixed-medium-r-normal--14-*-*-*-c-*-jisx0208.1983-0' knj = '-*-fixed-bold-r-normal--12-*-*-*-c-*-jisx0208.1983-0' when 'windows' ltn = {'family'=>'MS Sans Serif'.freeze, 'size'=>8} knj = 'mincho' when 'macintosh' ltn = 'system' knj = 'mincho' else # unknown ltn = 'Helvetica' knj = 'mincho' end end rescue ltn = 'Helvetica' knj = 'mincho' end else # not JAPANIZED_TK begin #platform = tk_call('set', 'tcl_platform(platform)') platform = Tk::PLATFORM['platform'] case platform when 'unix' ltn = {'family'=>'Helvetica'.freeze, 'size'=>-12, 'weight'=>'bold'.freeze} when 'windows' ltn = {'family'=>'MS Sans Serif'.freeze, 'size'=>8} when 'macintosh' ltn = 'system' else # unknown ltn = 'Helvetica' end rescue ltn = 'Helvetica' end knj = ltn.dup end DEFAULT_LATIN_FONT_NAME = ltn.freeze DEFAULT_KANJI_FONT_NAME = knj.freeze else # unknown version DEFAULT_LATIN_FONT_NAME = 'Helvetica'.freeze DEFAULT_KANJI_FONT_NAME = 'mincho'.freeze end if $DEBUG print "default latin font = "; p DEFAULT_LATIN_FONT_NAME print "default kanji font = "; p DEFAULT_KANJI_FONT_NAME end ################################### class DescendantFont def initialize(compound, type) unless compound.kind_of?(TkFont) fail ArgumentError, "a TkFont object is expected for the 1st argument" end @compound = compound case type when 'kanji', 'latin', 'ascii' @type = type when :kanji, :latin, :ascii @type = type.to_s else fail ArgumentError, "unknown type '#{type}'" end end def dup fail RuntimeError, "cannot dupulicate a descendant font" end def clone fail RuntimeError, "cannot clone a descendant font" end def to_eval @compound.__send__(@type + '_font_id') end def font @compound.__send__(@type + '_font_id') end def [](slot) @compound.__send__(@type + '_configinfo', slot) end def []=(slot, value) @compound.__send__(@type + '_configure', slot, value) value end def method_missing(id, *args) @compound.__send__(@type + '_' + id.id2name, *args) end end ################################### # class methods ################################### def TkFont.actual(fnt, option=nil) fnt = '{}' if fnt == '' if fnt.kind_of?(TkFont) fnt.actual(option) else actual_core(fnt, nil, option) end end def TkFont.actual_displayof(fnt, win, option=nil) fnt = '{}' if fnt == '' if fnt.kind_of?(TkFont) fnt.actual_displayof(win, option) else win = '.' unless win actual_core(fnt, win, option) end end def TkFont.configure(fnt, slot, value=None) if fnt.kind_of?(TkFont) fnt.configure(fnt, slot, value) else configure_core(fnt, slot, value) end fnt end def TkFont.configinfo(fnt, slot=nil) if fnt.kind_of?(TkFont) fnt.configinfo(fnt, slot) else configinfo_core(fnt, slot) end end def TkFont.current_configinfo(fnt, slot=nil) if fnt.kind_of?(TkFont) fnt.current_configinfo(fnt, slot) else current_configinfo_core(fnt, slot) end end def TkFont.measure(fnt, text) fnt = '{}' if fnt == '' if fnt.kind_of?(TkFont) fnt.measure(text) else measure_core(fnt, nil, text) end end def TkFont.measure_displayof(fnt, win, text) fnt = '{}' if fnt == '' if fnt.kind_of?(TkFont) fnt.measure_displayof(win, text) else win = '.' unless win measure_core(fnt, win, text) end end def TkFont.metrics(fnt, option=nil) fnt = '{}' if fnt == '' if fnt.kind_of?(TkFont) fnt.metrics(option) else metrics_core(fnt, nil, option) end end def TkFont.metrics_displayof(fnt, win, option=nil) fnt = '{}' if fnt == '' if fnt.kind_of?(TkFont) font.metrics_displayof(win, option=nil) else win = '.' unless win metrics_core(fnt, win, option) end end def TkFont.families(win=nil) case (Tk::TK_VERSION) when /^4\.*/ ['fixed'] when /^8\.*/ if win tk_split_simplelist(tk_call('font', 'families', '-displayof', win)) else tk_split_simplelist(tk_call('font', 'families')) end end end def TkFont.names case (Tk::TK_VERSION) when /^4\.*/ r = ['fixed'] r += ['a14', 'k14'] if JAPANIZED_TK Tk_FontNameTBL.each_value{|obj| r.push(obj)} r | [] when /^8\.*/ tk_split_simplelist(tk_call('font', 'names')) end end def TkFont.create_copy(font) fail 'source-font must be a TkFont object' unless font.kind_of? TkFont if TkComm::GET_CONFIGINFOwoRES_AS_ARRAY keys = {} font.configinfo.each{|key,value| keys[key] = value } TkFont.new(font.latin_font_id, font.kanji_font_id, keys) else # ! TkComm::GET_CONFIGINFOwoRES_AS_ARRAY TkFont.new(font.latin_font_id, font.kanji_font_id, font.configinfo) end end def TkFont.get_obj(name) if name =~ /^(@font[0-9]+)(|c|l|k)$/ Tk_FontNameTBL[$1] else nil end end def TkFont.init_widget_font(pathname, *args) win, tag, key = pathname.split(';') key = 'font' if key == nil || key == '' path = [win, tag, key].join(';') case (Tk::TK_VERSION) when /^4\.*/ regexp = /^-(|kanji)#{key} / conf_list = tk_split_simplelist(tk_call(*args)). find_all{|prop| prop =~ regexp}. collect{|prop| tk_split_simplelist(prop)} if conf_list.size == 0 raise RuntimeError, "the widget may not support 'font' option" end args << {} ltn_key = "-#{key}" knj_key = "-kanji#{key}" ltn_info = conf_list.find{|conf| conf[0] == ltn_key} ltn = ltn_info[-1] ltn = nil if ltn == [] || ltn == "" knj_info = conf_list.find{|conf| conf[0] == knj_key} knj = knj_info[-1] knj = nil if knj == [] || knj == "" TkFont.new(ltn, knj).call_font_configure([path, key], *args) when /^8\.*/ regexp = /^-#{key} / conf_list = tk_split_simplelist(tk_call(*args)). find_all{|prop| prop =~ regexp}. collect{|prop| tk_split_simplelist(prop)} if conf_list.size == 0 raise RuntimeError, "the widget may not support 'font' option" end args << {} optkey = "-#{key}" info = conf_list.find{|conf| conf[0] == optkey} fnt = info[-1] fnt = nil if fnt == [] || fnt == "" unless fnt # create dummy # TkFont.new(nil, nil).call_font_configure([path, key], *args) dummy_fnt = TkFont.allocate dummy_fnt.instance_eval{ init_dummy_fontobj() } dummy_fnt else begin compound = tk_split_simplelist( Hash[*tk_split_simplelist(tk_call('font', 'configure', fnt))].collect{|k,v| [k[1..-1], v] }.assoc('compound')[1]) rescue compound = [] end if compound == [] TkFont.new(fnt).call_font_configure([path, key], *args) else TkFont.new(compound[0], compound[1]).call_font_configure([path, key], *args) end end end end def TkFont.used_on(path=nil) if path Tk_FontUseTBL[path] else Tk_FontUseTBL.values | [] end end def TkFont.failsafe(font) begin if /^8\.*/ === Tk::TK_VERSION && JAPANIZED_TK tk_call('font', 'failsafe', font) end rescue end end ################################### # instance methods ################################### private ################################### def init_dummy_fontobj @id = Tk_FontID.join(TkCore::INTERP._ip_id_) Tk_FontID[1].succ! Tk_FontNameTBL[@id] = self @latin_desscendant = nil @kanji_desscendant = nil case (Tk::TK_VERSION) when /^4\.*/ @latinfont = "" @kanjifont = "" if JAPANIZED_TK @compoundfont = [[@latinfont], [@kanjifont]] @fontslot = {'font'=>@latinfont, 'kanjifont'=>@kanjifont} else @compoundfont = @latinfont @fontslot = {'font'=>@latinfont} end else @latinfont = @id + 'l' @kanjifont = @id + 'k' @compoundfont = @id + 'c' if JAPANIZED_TK tk_call('font', 'create', @latinfont, '-charset', 'iso8859') tk_call('font', 'create', @kanjifont, '-charset', 'jisx0208.1983') tk_call('font', 'create', @compoundfont, '-compound', [@latinfont, @kanjifont]) else tk_call('font', 'create', @latinfont) tk_call('font', 'create', @kanjifont) tk_call('font', 'create', @compoundfont) end @fontslot = {'font'=>@compoundfont} end self end def initialize(ltn=nil, knj=nil, keys=nil) ltn = '{}' if ltn == '' knj = '{}' if knj == '' # @id = Tk_FontID.join('') @id = Tk_FontID.join(TkCore::INTERP._ip_id_) Tk_FontID[1].succ! Tk_FontNameTBL[@id] = self @latin_desscendant = nil @kanji_desscendant = nil if knj.kind_of?(Hash) && !keys keys = knj knj = nil end # compound font check if Tk::TK_VERSION == '8.0' && JAPANIZED_TK begin compound = tk_split_simplelist(tk_call('font', 'configure', ltn, '-compound')) if knj == nil if compound != [] ltn, knj = compound end else if compound != [] ltn = compound[0] end compound = tk_split_simplelist(tk_call('font', 'configure', knj, '-compound')) if compound != [] knj = compound[1] end end rescue end end if ltn if JAPANIZED_TK && !knj if Tk::TK_VERSION =~ /^4.*/ knj = DEFAULT_KANJI_FONT_NAME else knj = ltn end end else ltn = DEFAULT_LATIN_FONT_NAME knj = DEFAULT_KANJI_FONT_NAME if JAPANIZED_TK && !knj end create_compoundfont(ltn, knj, keys) end def initialize_copy(font) unless font.kind_of?(TkFont) fail TypeError, '"initialize_copy should take same class object' end if TkComm::GET_CONFIGINFOwoRES_AS_ARRAY keys = {} font.configinfo.each{|key,value| keys[key] = value } initialize(font.latin_font_id, font.kanji_font_id, keys) else # ! TkComm::GET_CONFIGINFOwoRES_AS_ARRAY initialize(font.latin_font_id, font.kanji_font_id, font.configinfo) end end def _get_font_info_from_hash(font) font = _symbolkey2str(font) foundry = (info = font['foundry'] .to_s)? info: '*' family = (info = font['family'] .to_s)? info: '*' weight = (info = font['weight'] .to_s)? info: '*' slant = (info = font['slant'] .to_s)? info: '*' swidth = (info = font['swidth'] .to_s)? info: '*' adstyle = (info = font['adstyle'] .to_s)? info: '*' pixels = (info = font['pixels'] .to_s)? info: '*' points = (info = font['points'] .to_s)? info: '*' resx = (info = font['resx'] .to_s)? info: '*' resy = (info = font['resy'] .to_s)? info: '*' space = (info = font['space'] .to_s)? info: '*' avgWidth = (info = font['avgWidth'].to_s)? info: '*' charset = (info = font['charset'] .to_s)? info: '*' encoding = (info = font['encoding'].to_s)? info: '*' [foundry, family, weight, slant, swidth, adstyle, pixels, points, resx, resy, space, avgWidth, charset, encoding] end def create_latinfont_tk4x(font) if font.kind_of? Hash @latinfont = '-' + _get_font_info_from_hash(font).join('-') + '-' elsif font.kind_of? Array finfo = {} finfo['family'] = font[0].to_s if font[1] fsize = font[1].to_s if fsize != '0' && fsize =~ /^(|\+|-)([0-9]+)$/ if $1 == '-' finfo['pixels'] = $2 else finfo['points'] = $2 end else finfo['points'] = '13' end end font[2..-1].each{|style| case (style) when 'normal' finfo['weight'] = style when 'bold' finfo['weight'] = style when 'roman' finfo['slant'] = 'r' when 'italic' finfo['slant'] = 'i' end } @latinfont = '-' + _get_font_info_from_hash(finfo).join('-') + '-' elsif font.kind_of? TkFont @latinfont = font.latin_font else if font @latinfont = font else @latinfont = DEFAULT_LATIN_FONT_NAME end end end def create_kanjifont_tk4x(font) unless JAPANIZED_TK @kanjifont = "" return end if font.kind_of? Hash @kanjifont = '-' + _get_font_info_from_hash(font).join('-') + '-' elsif font.kind_of? Array finfo = {} finfo['family'] = font[0].to_s if font[1] fsize = font[1].to_s if fsize != '0' && fsize =~ /^(|\+|-)([0-9]+)$/ if $1 == '-' finfo['pixels'] = $2 else finfo['points'] = $2 end else finfo['points'] = '13' end end font[2..-1].each{|style| case (style) when 'normal' finfo['weight'] = style when 'bold' finfo['weight'] = style when 'roman' finfo['slant'] = 'r' when 'italic' finfo['slant'] = 'i' end } @kanjifont = '-' + _get_font_info_from_hash(finfo).join('-') + '-' elsif font.kind_of? TkFont @kanjifont = font.kanji_font_id else if font @kanjifont = font else @kanjifont = DEFAULT_KANJI_FONT_NAME end end end def create_compoundfont_tk4x(ltn, knj, keys) create_latinfont(ltn) create_kanjifont(knj) if JAPANIZED_TK @compoundfont = [[@latinfont], [@kanjifont]] @fontslot = {'font'=>@latinfont, 'kanjifont'=>@kanjifont} else @compoundfont = @latinfont @fontslot = {'font'=>@latinfont} end end def create_latinfont_tk8x(font) @latinfont = @id + 'l' if JAPANIZED_TK if font.kind_of? Hash if font[:charset] || font['charset'] tk_call('font', 'create', @latinfont, *hash_kv(font)) else tk_call('font', 'create', @latinfont, '-charset', 'iso8859', *hash_kv(font)) end elsif font.kind_of? Array tk_call('font', 'create', @latinfont, '-copy', array2tk_list(font)) tk_call('font', 'configure', @latinfont, '-charset', 'iso8859') elsif font.kind_of? TkFont tk_call('font', 'create', @latinfont, '-copy', font.latin_font) elsif font tk_call('font', 'create', @latinfont, '-copy', font, '-charset', 'iso8859') else tk_call('font', 'create', @latinfont, '-charset', 'iso8859') end else if font.kind_of? Hash tk_call('font', 'create', @latinfont, *hash_kv(font)) else keys = {} if font.kind_of? Array actual_core(array2tk_list(font)).each{|key,val| keys[key] = val} elsif font.kind_of? TkFont actual_core(font.latin_font).each{|key,val| keys[key] = val} elsif font actual_core(font).each{|key,val| keys[key] = val} end tk_call('font', 'create', @latinfont, *hash_kv(keys)) end if font && @compoundfont keys = {} actual_core(@latinfont).each{|key,val| keys[key] = val} tk_call('font', 'configure', @compoundfont, *hash_kv(keys)) end end end def create_kanjifont_tk8x(font) @kanjifont = @id + 'k' if JAPANIZED_TK if font.kind_of? Hash if font[:charset] || font['charset'] tk_call('font', 'create', @kanjifont, *hash_kv(font)) else tk_call('font', 'create', @kanjifont, '-charset', 'jisx0208.1983', *hash_kv(font)) end elsif font.kind_of? Array tk_call('font', 'create', @kanjifont, '-copy', array2tk_list(font)) tk_call('font', 'configure', @kanjifont, '-charset', 'jisx0208.1983') elsif font.kind_of? TkFont tk_call('font', 'create', @kanjifont, '-copy', font.kanji_font_id) elsif font tk_call('font', 'create', @kanjifont, '-copy', font, '-charset', 'jisx0208.1983') else tk_call('font', 'create', @kanjifont, '-charset', 'jisx0208.1983') end # end of JAPANIZED_TK else if font.kind_of? Hash tk_call('font', 'create', @kanjifont, *hash_kv(font)) else keys = {} if font.kind_of? Array actual_core(array2tk_list(font)).each{|key,val| keys[key] = val} elsif font.kind_of? TkFont actual_core(font.kanji_font_id).each{|key,val| keys[key] = val} elsif font actual_core(font).each{|key,val| keys[key] = val} end tk_call('font', 'create', @kanjifont, *hash_kv(keys)) end if font && @compoundfont keys = {} actual_core(@kanjifont).each{|key,val| keys[key] = val} tk_call('font', 'configure', @compoundfont, *hash_kv(keys)) end end end def create_compoundfont_tk8x(ltn, knj, keys) if knj create_latinfont(ltn) create_kanjifont(knj) else cfnt = ltn create_kanjifont(cfnt) create_latinfont(cfnt) end @compoundfont = @id + 'c' if JAPANIZED_TK unless keys keys = {} else keys = keys.dup end if (tk_call('font', 'configure', @latinfont, '-underline') == '1' && tk_call('font', 'configure', @kanjifont, '-underline') == '1' && !keys.key?('underline')) keys['underline'] = true end if (tk_call('font', 'configure', @latinfont, '-overstrike') == '1' && tk_call('font', 'configure', @kanjifont, '-overstrike') == '1' && !keys.key?('overstrike')) keys['overstrike'] = true end @fontslot = {'font'=>@compoundfont} begin tk_call('font', 'create', @compoundfont, '-compound', [@latinfont, @kanjifont], *hash_kv(keys)) rescue RuntimeError => e if ltn == knj if e.message =~ /kanji font .* specified/ tk_call('font', 'delete', @latinfont) create_latinfont(DEFAULT_LATIN_FONT_NAME) opts = [] Hash[*(tk_split_simplelist(tk_call('font', 'configure', @kanjifont)))].each{|k,v| case k when '-size', '-weight', '-slant', '-underline', '-overstrike' opts << k << v end } tk_call('font', 'configure', @latinfont, *opts) tk_call('font', 'create', @compoundfont, '-compound', [@latinfont, @kanjifont], *hash_kv(keys)) elsif e.message =~ /ascii font .* specified/ tk_call('font', 'delete', @kanjifont) create_kanjifont(DEFAULT_KANJI_FONT_NAME) opts = [] Hash[*(tk_split_simplelist(tk_call('font', 'configure', @latinfont)))].each{|k,v| case k when '-size', '-weight', '-slant', '-underline', '-overstrike' opts << k << v end } tk_call('font', 'configure', @kanjifont, *opts) tk_call('font', 'create', @compoundfont, '-compound', [@latinfont, @kanjifont], *hash_kv(keys)) else raise e end else raise e end end else tk_call('font', 'create', @compoundfont) latinkeys = {} begin actual_core(@latinfont).each{|key,val| latinkeys[key] = val} rescue latinkeys = {} end if latinkeys != {} tk_call('font', 'configure', @compoundfont, *hash_kv(latinkeys)) end if knj compoundkeys = nil kanjikeys = {} begin actual_core(@kanjifont).each{|key,val| kanjikeys[key] = val} rescue kanjikeys = {} end if kanjikeys != {} tk_call('font', 'configure', @compoundfont, *hash_kv(kanjikeys)) end end if cfnt if cfnt.kind_of?(Hash) compoundkeys = cfnt.dup else compoundkeys = {} actual_core(cfnt).each{|key,val| compoundkeys[key] = val} end compoundkeys.update(_symbolkey2str(keys)) keys = compoundkeys end @fontslot = {'font'=>@compoundfont} tk_call('font', 'configure', @compoundfont, *hash_kv(keys)) end end ################################### public ################################### def inspect sprintf("#<%s:%0x:%s>", self.class.inspect, self.__id__, @compoundfont) end def method_missing(id, *args) name = id.id2name case args.length when 1 if name[-1] == ?= configure name[0..-2], args[0] args[0] else configure name, args[0] self end when 0 begin configinfo name rescue super(id, *args) # fail NameError, "undefined local variable or method `#{name}' for #{self.to_s}", error_at end else super(id, *args) # fail NameError, "undefined method `#{name}' for #{self.to_s}", error_at end end def call_font_configure(path, *args) if path.kind_of?(Array) # [path, optkey] win, tag = path[0].split(';') optkey = path[1].to_s else win, tag, optkey = path.split(';') end fontslot = _symbolkey2str(@fontslot) if optkey && optkey != "" ltn = fontslot.delete('font') knj = fontslot.delete('kanjifont') fontslot[optkey] = ltn if ltn fontslot["kanji#{optkey}"] = knj if knj end keys = _symbolkey2str(args.pop).update(fontslot) args.concat(hash_kv(keys)) tk_call(*args) Tk_FontUseTBL[[win, tag, optkey].join(';')] = self self end def used ret = [] Tk_FontUseTBL.each{|key,value| next unless self == value if key.include?(';') win, tag, optkey = key.split(';') winobj = tk_tcl2ruby(win) if winobj.kind_of? TkText if optkey ret.push([winobj, winobj.tagid2obj(tag), optkey]) else ret.push([winobj, winobj.tagid2obj(tag)]) end elsif winobj.kind_of? TkCanvas if (tagobj = TkcTag.id2obj(winobj, tag)).kind_of? TkcTag if optkey ret.push([winobj, tagobj, optkey]) else ret.push([winobj, tagobj]) end elsif (tagobj = TkcItem.id2obj(winobj, tag)).kind_of? TkcItem if optkey ret.push([winobj, tagobj, optkey]) else ret.push([winobj, tagobj]) end else if optkey ret.push([winobj, tag, optkey]) else ret.push([winobj, tag]) end end elsif winobj.kind_of? TkMenu if optkey ret.push([winobj, tag, optkey]) else ret.push([winobj, tag]) end else if optkey ret.push([win, tag, optkey]) else ret.push([win, tag]) end end else ret.push(tk_tcl2ruby(key)) end } ret end def id @id end def to_eval font end def font @compoundfont end alias font_id font def latin_font_id @latinfont end def latin_font # @latinfont if @latin_descendant @latin_descendant else @latin_descendant = DescendantFont.new(self, 'latin') end end alias latinfont latin_font def kanji_font_id @kanjifont end def kanji_font # @kanjifont if @kanji_descendant @kanji_descendant else @kanji_descendant = DescendantFont.new(self, 'kanji') end end alias kanjifont kanji_font def actual(option=nil) actual_core(@compoundfont, nil, option) end def actual_displayof(win, option=nil) win = '.' unless win actual_core(@compoundfont, win, option) end def latin_actual(option=nil) actual_core(@latinfont, nil, option) end def latin_actual_displayof(win, option=nil) win = '.' unless win actual_core(@latinfont, win, option) end def kanji_actual(option=nil) #if JAPANIZED_TK if @kanjifont != "" actual_core(@kanjifont, nil, option) else actual_core_tk4x(nil, nil, option) end end def kanji_actual_displayof(win, option=nil) #if JAPANIZED_TK if @kanjifont != "" win = '.' unless win actual_core(@kanjifont, win, option) else actual_core_tk4x(nil, win, option) end end def [](slot) configinfo slot end def []=(slot, val) configure slot, val val end def configure(slot, value=None) configure_core(@compoundfont, slot, value) self end def configinfo(slot=nil) configinfo_core(@compoundfont, slot) end def current_configinfo(slot=nil) current_configinfo_core(@compoundfont, slot) end def delete delete_core end def latin_configure(slot, value=None) if JAPANIZED_TK configure_core(@latinfont, slot, value) else configure(slot, value) end self end def latin_configinfo(slot=nil) if JAPANIZED_TK configinfo_core(@latinfont, slot) else configinfo(slot) end end def kanji_configure(slot, value=None) #if JAPANIZED_TK if @kanjifont != "" configure_core(@kanjifont, slot, value) configure('size'=>configinfo('size')) # to reflect new configuration else #"" configure(slot, value) end self end def kanji_configinfo(slot=nil) #if JAPANIZED_TK if @kanjifont != "" configinfo_core(@kanjifont, slot) else #[] configinfo(slot) end end def replace(ltn, knj=None) knj = ltn if knj == None latin_replace(ltn) kanji_replace(knj) self end def latin_replace(ltn) latin_replace_core(ltn) reset_pointadjust self end def kanji_replace(knj) kanji_replace_core(knj) reset_pointadjust self end def measure(text) measure_core(@compoundfont, nil, text) end def measure_displayof(win, text) win = '.' unless win measure_core(@compoundfont, win, text) end def metrics(option=nil) metrics_core(@compoundfont, nil, option) end def metrics_displayof(win, option=nil) win = '.' unless win metrics_core(@compoundfont, win, option) end def latin_metrics(option=nil) metrics_core(@latinfont, nil, option) end def latin_metrics_displayof(win, option=nil) win = '.' unless win metrics_core(@latinfont, win, option) end def kanji_metrics(option=nil) if JAPANIZED_TK metrics_core(@kanjifont, nil, option) else metrics_core_tk4x(nil, nil, option) end end def kanji_metrics_displayof(win, option=nil) if JAPANIZED_TK win = '.' unless win metrics_core(@kanjifont, win, option) else metrics_core_tk4x(nil, win, option) end end def reset_pointadjust begin if /^8\.*/ === Tk::TK_VERSION && JAPANIZED_TK configure('pointadjust' => latin_actual.assoc('size')[1].to_f / kanji_actual.assoc('size')[1].to_f ) end rescue end self end ################################### # private alias ################################### case (Tk::TK_VERSION) when /^4\.*/ alias create_latinfont create_latinfont_tk4x alias create_kanjifont create_kanjifont_tk4x alias create_compoundfont create_compoundfont_tk4x when /^8\.[0-5]/ alias create_latinfont create_latinfont_tk8x alias create_kanjifont create_kanjifont_tk8x alias create_compoundfont create_compoundfont_tk8x else alias create_latinfont create_latinfont_tk8x alias create_kanjifont create_kanjifont_tk8x alias create_compoundfont create_compoundfont_tk8x end ################################### # public alias ################################### alias ascii_font latin_font alias asciifont latinfont alias create_asciifont create_latinfont alias ascii_actual latin_actual alias ascii_actual_displayof latin_actual_displayof alias ascii_configure latin_configure alias ascii_configinfo latin_configinfo alias ascii_replace latin_replace alias ascii_metrics latin_metrics ################################### =begin def dup TkFont.new(self) end def clone TkFont.new(self) end =end end module TkFont::CoreMethods include Tk extend TkCore private def actual_core_tk4x(font, win=nil, option=nil) # dummy if option == 'pointadjust' || option == :pointadjust 1.0 elsif option case TkFont::OptionType[option.to_s] when ?n 0 when ?b false else '' end else [['family',''], ['size',0], ['weight',''], ['slant',''], ['underline',false], ['overstrike',false], ['charset',''], ['pointadjust',0]] end end def actual_core_tk8x(font, win=nil, option=nil) font = '{}' if font == '' if option == 'compound' || option == :compound "" elsif option if win val = tk_call('font', 'actual', font, "-displayof", win, "-#{option}") else val = tk_call('font', 'actual', font, "-#{option}") end case TkFont::OptionType[option.to_s] when ?n num_or_str(val) when ?b bool(val) else val end else l = tk_split_simplelist(if win tk_call('font', 'actual', font, "-displayof", win) else tk_call('font', 'actual', font) end) r = [] while key=l.shift if key == '-compound' l.shift else key = key[1..-1] val = l.shift case TkFont::OptionType[key] when ?n r.push [key, num_or_str(val)] when ?b r.push [key, bool(val)] else r.push [key, val] end end end r end end def configure_core_tk4x(font, slot, value=None) #"" self end def configinfo_core_tk4x(font, option=nil) # dummy if TkComm::GET_CONFIGINFOwoRES_AS_ARRAY if option == 'pointadjust' || option == :pointadjust 1.0 elsif option case TkFont::OptionType[option.to_s] when ?n 0 when ?b false else '' end else [['family',''], ['size',0], ['weight',''], ['slant',''], ['underline',false], ['overstrike',false], ['charset',''], ['pointadjust',1.0]] end else # ! TkComm::GET_CONFIGINFOwoRES_AS_ARRAY current_configinfo_core_tk4x(font, option) end end def current_configinfo_core_tk4x(font, option=nil) if option case TkFont::OptionType[option.to_s] when ?n 0 when ?b false else '' end else {'family'=>'', 'size'=>0, 'weight'=>'', 'slant'=>'', 'underline'=>false, 'overstrike'=>false, 'charset'=>false, 'pointadjust'=>1.0} end end def configure_core_tk8x(font, slot, value=None) if JAPANIZED_TK begin padjust = tk_call('font', 'configure', font, '-pointadjust') rescue padjust = nil end else padjust = nil end if slot.kind_of? Hash if JAPANIZED_TK && (slot.key?('family') || slot.key?(:family)) slot = _symbolkey2str(slot) configure_core_tk8x(font, 'family', slot.delete('family')) end if ((slot.key?('size') || slot.key?(:size)) && padjust && !slot.key?('pointadjust') && !slot.key?(:pointadjust)) tk_call('font', 'configure', font, '-pointadjust', padjust, *hash_kv(slot)) else tk_call('font', 'configure', font, *hash_kv(slot)) end elsif (slot == 'size' || slot == :size) && padjust != nil tk_call('font', 'configure', font, "-#{slot}", value, '-pointadjust', padjust) elsif JAPANIZED_TK && (slot == 'family' || slot == :family) # coumpund font? begin compound = tk_split_simplelist(tk_call('font', 'configure', font, '-compound')) rescue tk_call('font', 'configure', font, '-family', value) return self end if compound == [] tk_call('font', 'configure', font, '-family', value) return self end ltn, knj = compound lfnt = tk_call('font', 'create', '-copy', ltn) begin tk_call('font', 'configure', lfnt, '-family', value) latin_replace_core_tk8x(lfnt) rescue RuntimeError => e fail e if $DEBUG ensure tk_call('font', 'delete', lfnt) if lfnt != '' end kfnt = tk_call('font', 'create', '-copy', knj) begin tk_call('font', 'configure', kfnt, '-family', value) kanji_replace_core_tk8x(lfnt) rescue RuntimeError => e fail e if $DEBUG ensure tk_call('font', 'delete', kfnt) if kfnt != '' end else tk_call('font', 'configure', font, "-#{slot}", value) end self end def configinfo_core_tk8x(font, option=nil) if TkComm::GET_CONFIGINFOwoRES_AS_ARRAY if option == 'compound' || option == :compound "" elsif option val = tk_call('font', 'configure', font, "-#{option}") case TkFont::OptionType[option.to_s] when ?n num_or_str(val) when ?b bool(val) else val end else l = tk_split_simplelist(tk_call('font', 'configure', font)) r = [] while key=l.shift if key == '-compound' l.shift else key = key[1..-1] val = l.shift case TkFont::OptionType[key] when ?n r.push [key, num_or_str(val)] when ?b r.push [key, bool(val)] else r.push [key, val] end end end r end else # ! TkComm::GET_CONFIGINFOwoRES_AS_ARRAY current_configinfo_core_tk8x(font, option) end end def current_configinfo_core_tk8x(font, option=nil) if option == 'compound' "" elsif option val = tk_call('font', 'configure', font, "-#{option}") case TkFont::OptionType[option.to_s] when ?n num_or_str(val) when ?b bool(val) else val end else l = tk_split_simplelist(tk_call('font', 'configure', font)) r = {} while key=l.shift if key == '-compound' l.shift else key = key[1..-1] val = l.shift case TkFont::OptionType[key] when ?n r.push [key, num_or_str(val)] when ?b r.push [key, bool(val)] else r.push [key, val] end end end r end end def delete_core_tk4x TkFont::Tk_FontNameTBL.delete(@id) TkFont::Tk_FontUseTBL.delete_if{|key,value| value == self} end def delete_core_tk8x begin tk_call('font', 'delete', @latinfont) rescue end begin tk_call('font', 'delete', @kanjifont) rescue end begin tk_call('font', 'delete', @compoundfont) rescue end TkFont::Tk_FontNameTBL.delete(@id) TkFont::Tk_FontUseTBL.delete_if{|key,value| value == self} end def latin_replace_core_tk4x(ltn) create_latinfont_tk4x(ltn) @compoundfont[0] = [@latinfont] if JAPANIZED_TK @fontslot['font'] = @latinfont TkFont::Tk_FontUseTBL.dup.each{|w, fobj| if self == fobj begin if w.include?(';') win, tag, optkey = w.split(';') optkey = 'font' if optkey == nil || optkey == '' winobj = tk_tcl2ruby(win) # winobj.tagfont_configure(tag, {'font'=>@latinfont}) if winobj.kind_of? TkText tk_call(win, 'tag', 'configure', tag, "-#{optkey}", @latinfont) elsif winobj.kind_of? TkCanvas tk_call(win, 'itemconfigure', tag, "-#{optkey}", @latinfont) elsif winobj.kind_of? TkMenu tk_call(win, 'entryconfigure', tag, "-#{optkey}", @latinfont) else raise RuntimeError, "unknown widget type" end else # tk_tcl2ruby(w).font_configure('font'=>@latinfont) tk_call(w, 'configure', '-font', @latinfont) end rescue TkFont::Tk_FontUseTBL.delete(w) end end } self end def kanji_replace_core_tk4x(knj) return self unless JAPANIZED_TK create_kanjifont_tk4x(knj) @compoundfont[1] = [@kanjifont] @fontslot['kanjifont'] = @kanjifont TkFont::Tk_FontUseTBL.dup.each{|w, fobj| if self == fobj begin if w.include?(';') win, tag, optkey = w.split(';') optkey = 'kanjifont' unless optkey winobj = tk_tcl2ruby(win) # winobj.tagfont_configure(tag, {'kanjifont'=>@kanjifont}) if winobj.kind_of? TkText tk_call(win, 'tag', 'configure', tag, "-#{optkey}", @kanjifont) elsif winobj.kind_of? TkCanvas tk_call(win, 'itemconfigure', tag, "-#{optkey}", @kanjifont) elsif winobj.kind_of? TkMenu tk_call(win, 'entryconfigure', tag, "-#{optkey}", @latinfont) else raise RuntimeError, "unknown widget type" end else # tk_tcl2ruby(w).font_configure('kanjifont'=>@kanjifont) tk_call(w, 'configure', '-kanjifont', @kanjifont) end rescue TkFont::Tk_FontUseTBL.delete(w) end end } self end def latin_replace_core_tk8x(ltn) ltn = '{}' if ltn == '' if JAPANIZED_TK begin tk_call('font', 'delete', '@font_tmp') rescue end begin fnt_bup = tk_call('font', 'create', '@font_tmp', '-copy', @latinfont) rescue #fnt_bup = '' fnt_bup = TkFont::DEFAULT_LATIN_FONT_NAME end end begin tk_call('font', 'delete', @latinfont) rescue end create_latinfont(ltn) if JAPANIZED_TK keys = self.configinfo tk_call('font', 'delete', @compoundfont) begin tk_call('font', 'create', @compoundfont, '-compound', [@latinfont, @kanjifont], *hash_kv(keys)) =begin latinkeys = {} begin actual_core(@latinfont).each{|key,val| latinkeys[key] = val} rescue latinkeys = {} end if latinkeys != {} tk_call('font', 'configure', @compoundfont, *hash_kv(latinkeys)) end =end rescue RuntimeError => e tk_call('font', 'delete', @latinfont) if fnt_bup && fnt_bup != '' tk_call('font', 'create', @latinfont, '-copy', fnt_bup) tk_call('font', 'create', @compoundfont, '-compound', [@latinfont, @kanjifont], *hash_kv(keys)) tk_call('font', 'delete', fnt_bup) else fail e end end else latinkeys = {} begin actual_core(@latinfont).each{|key,val| latinkeys[key] = val} rescue latinkeys = {} end if latinkeys != {} tk_call('font', 'configure', @compoundfont, *hash_kv(latinkeys)) end end self end def kanji_replace_core_tk8x(knj) knj = '{}' if knj == '' if JAPANIZED_TK begin tk_call('font', 'delete', '@font_tmp') rescue end begin fnt_bup = tk_call('font', 'create', '@font_tmp', '-copy', @kanjifont) rescue #fnt_bup = '' fnt_bup = TkFont::DEFAULT_KANJI_FONT_NAME end end begin tk_call('font', 'delete', @kanjifont) rescue end create_kanjifont(knj) if JAPANIZED_TK keys = self.configinfo tk_call('font', 'delete', @compoundfont) begin tk_call('font', 'create', @compoundfont, '-compound', [@latinfont, @kanjifont], *hash_kv(keys)) rescue RuntimeError => e tk_call('font', 'delete', @kanjifont) if fnt_bup && fnt_bup != '' tk_call('font', 'create', @kanjifont, '-copy', fnt_bup) tk_call('font', 'create', @compoundfont, '-compound', [@latinfont, @kanjifont], *hash_kv(keys)) tk_call('font', 'delete', fnt_bup) else fail e end end end self end def measure_core_tk4x(font, win, text) 0 end def measure_core_tk8x(font, win, text) font = '{}' if font == '' if win number(tk_call('font', 'measure', font, '-displayof', win, text)) else number(tk_call('font', 'measure', font, text)) end end def metrics_core_tk4x(font, win, option=nil) # dummy if option "" else [['ascent',[]], ['descent',[]], ['linespace',[]], ['fixed',[]]] end end def metrics_core_tk8x(font, win, option=nil) font = '{}' if font == '' if option if win number(tk_call('font', 'metrics', font, "-displayof", win, "-#{option}")) else number(tk_call('font', 'metrics', font, "-#{option}")) end else l = tk_split_list(if win tk_call('font','metrics',font,"-displayof",win) else tk_call('font','metrics',font) end) r = [] while key=l.shift r.push [key[1..-1], l.shift.to_i] end r end end ################################### # private alias ################################### case (Tk::TK_VERSION) when /^4\.*/ alias actual_core actual_core_tk4x alias configure_core configure_core_tk4x alias configinfo_core configinfo_core_tk4x alias current_configinfo_core current_configinfo_core_tk4x alias delete_core delete_core_tk4x alias latin_replace_core latin_replace_core_tk4x alias kanji_replace_core kanji_replace_core_tk4x alias measure_core measure_core_tk4x alias metrics_core metrics_core_tk4x when /^8\.[0-5]/ alias actual_core actual_core_tk8x alias configure_core configure_core_tk8x alias configinfo_core configinfo_core_tk8x alias current_configinfo_core current_configinfo_core_tk8x alias delete_core delete_core_tk8x alias latin_replace_core latin_replace_core_tk8x alias kanji_replace_core kanji_replace_core_tk8x alias measure_core measure_core_tk8x alias metrics_core metrics_core_tk8x else alias actual_core actual_core_tk8x alias configure_core configure_core_tk8x alias configinfo_core configinfo_core_tk8x alias current_configinfo_core current_configinfo_core_tk8x alias delete_core delete_core_tk8x alias latin_replace_core latin_replace_core_tk8x alias kanji_replace_core kanji_replace_core_tk8x alias measure_core measure_core_tk8x alias metrics_core metrics_core_tk8x end end class TkFont include TkFont::CoreMethods extend TkFont::CoreMethods end