File: tk/font.rb

Overview
Module Structure
Class Hierarchy
Code

Overview

Module Structure

  module: <Toplevel Module>
  class: TkFont#8, #2227
extends
  TkCore   
  CoreMethods ( TkFont )
includes
  Tk   
  CoreMethods ( TkFont )
inherits from
  Object ( Builtin-Module )
has properties
constant: TkCommandNames #12
constant: Tk_FontID #14
method: mutex #16
constant: Tk_FontNameTBL #20
constant: Tk_FontUseTBL #21
constant: OptionType #29
constant: MetricType #36
constant: SYSTEM_FONT_NAMES #40
constant: DEFAULT_LATIN_FONT_NAME #55
constant: DEFAULT_KANJI_FONT_NAME #56
class method: is_system_font? / 1 #197
class method: actual (1/2) / 2 #205
class method: actual_hash (1/2) / 2 #213
class method: actual_displayof (1/2) / 3 #217
class method: actual_hash_displayof (1/2) / 2 #226
class method: configure (1/2) / 3 #230
class method: configinfo (1/2) / 2 #239
class method: current_configinfo (1/2) / 2 #247
class method: measure (1/2) / 2 #255
class method: measure_displayof (1/2) / 3 #264
class method: metrics (1/2) / 2 #274
class method: metrics_hash (1/2) / 2 #282
class method: metrics_displayof (1/2) / 3 #310
class method: metrics_hash_displayof (1/2) / 3 #319
class method: families / 1 #347
class method: names #361
class method: create_copy / 1 #378
class method: get_obj / 1 #389
class method: init_widget_font / 2 #402
class method: used_on / 1 #516
class method: failsafe / 1 #527
method: init_dummy_fontobj #541
method: initialize / 3 #587
method: initialize_copy / 1 #653
method: _get_font_info_from_hash / 1 #666
method: create_latinfont_tk4x / 1 #687
method: create_kanjifont_tk4x / 1 #734
method: create_compoundfont_tk4x / 3 #783
method: create_latinfont_tk8x / 1 #801
method: create_kanjifont_tk8x / 1 #846
method: create_compoundfont_tk8x / 3 #893
method: inspect #1012
method: method_missing / 2 #1016
method: call_font_configure / 2 #1040
method: used #1072
method: id #1132
method: to_eval #1136
method: font #1140
alias: font_id font #1143
alias: name font #1144
alias: to_s font #1145
method: latin_font_id #1147
method: latin_font #1151
alias: latinfont latin_font #1166
method: kanji_font_id #1168
method: kanji_font #1172
alias: kanjifont kanji_font #1187
method: actual (2/E) / 1 #1189
method: actual_hash (2/E) / 1 #1192
method: actual_displayof (2/E) / 2 #1196
method: actual_hash_displayof (2/E) / 2 #1200
method: latin_actual / 1 #1204
method: latin_actual_hash / 1 #1211
method: latin_actual_displayof / 2 #1215
method: latin_actual_hash_displayof / 2 #1223
method: kanji_actual / 1 #1227
method: kanji_actual_hash / 1 #1237
method: kanji_actual_displayof / 2 #1241
method: kanji_actual_hash_displayof / 2 #1252
method: [] / 1 #1256
method: []= / 2 #1260
method: configure (2/E) / 2 #1265
method: configinfo (2/E) / 1 #1270
method: current_configinfo (2/E) / 1 #1274
method: delete #1278
method: latin_configure / 2 #1282
method: latin_configinfo / 1 #1291
method: latin_current_configinfo / 1 #1298
method: kanji_configure / 2 #1302
method: kanji_configinfo / 1 #1316
method: kanji_current_configinfo / 1 #1327
method: replace / 2 #1331
method: latin_replace / 1 #1338
method: kanji_replace / 1 #1361
method: measure (2/E) / 1 #1368
method: measure_displayof (2/E) / 2 #1372
method: metrics (2/E) / 1 #1377
method: metrics_hash (2/E) / 1 #1380
method: metrics_displayof (2/E) / 2 #1408
method: metrics_hash_displayof (2/E) / 2 #1412
method: latin_metrics / 1 #1440
method: latin_metrics_hash / 1 #1447
method: latin_metrics_displayof / 2 #1475
method: latin_metrics_hash_displayof / 2 #1483
method: kanji_metrics / 1 #1511
method: kanji_metrics_hash / 1 #1520
method: kanji_metrics_displayof / 2 #1548
method: kanji_metrics_hash_displayof / 2 #1558
method: reset_pointadjust #1586
alias: create_latinfont (1/3) create_latinfont_tk4x #1602
alias: create_kanjifont (1/3) create_kanjifont_tk4x #1603
alias: create_compoundfont (1/3) create_compoundfont_tk4x #1604
alias: create_latinfont (2/3) create_latinfont_tk8x #1607
alias: create_kanjifont (2/3) create_kanjifont_tk8x #1608
alias: create_compoundfont (2/3) create_compoundfont_tk8x #1609
alias: create_latinfont (3/E) create_latinfont_tk8x #1612
alias: create_kanjifont (3/E) create_kanjifont_tk8x #1613
alias: create_compoundfont (3/E) create_compoundfont_tk8x #1614
alias: ascii_font latin_font #1621
alias: asciifont latinfont #1622
alias: create_asciifont create_latinfont #1623
alias: ascii_actual latin_actual #1624
alias: ascii_actual_displayof latin_actual_displayof #1625
alias: ascii_configure latin_configure #1626
alias: ascii_configinfo latin_configinfo #1627
alias: ascii_replace latin_replace #1628
alias: ascii_metrics latin_metrics #1629
  class: DescendantFont#146
inherits from
  Object ( Builtin-Module )
has properties
method: initialize / 2 #147
method: dup #163
method: clone #166
method: to_eval #170
method: font #173
alias: font_id font #176
alias: name font #177
alias: to_s font #178
method: [] / 1 #180
method: []= / 2 #183
method: method_missing / 2 #188
  module: CoreMethods#1642
extends
  TkCore   
includes
  Tk   
has properties
method: actual_core_tk4x / 3 #1648
method: actual_core_tk8x / 3 #1668
method: configure_core_tk4x / 3 #1716
method: configinfo_core_tk4x / 2 #1721
method: current_configinfo_core_tk4x / 2 #1745
method: configure_core_tk8x / 3 #1762
method: configinfo_core_tk8x / 2 #1829
method: current_configinfo_core_tk8x / 2 #1869
method: delete_core_tk4x #1905
method: delete_core_tk8x #1914
method: latin_replace_core_tk4x / 1 #1935
method: kanji_replace_core_tk4x / 1 #1977
method: latin_replace_core_tk8x / 1 #2021
method: kanji_replace_core_tk8x / 1 #2089
method: measure_core_tk4x / 3 #2132
method: measure_core_tk8x / 3 #2136
method: metrics_core_tk4x / 3 #2147
method: metrics_core_tk8x / 3 #2156
alias: actual_core (1/3) actual_core_tk4x #2192
alias: configure_core (1/3) configure_core_tk4x #2193
alias: configinfo_core (1/3) configinfo_core_tk4x #2194
alias: current_configinfo_core (1/3) current_configinfo_core_tk4x #2195
alias: delete_core (1/3) delete_core_tk4x #2196
alias: latin_replace_core (1/3) latin_replace_core_tk4x #2197
alias: kanji_replace_core (1/3) kanji_replace_core_tk4x #2198
alias: measure_core (1/3) measure_core_tk4x #2199
alias: metrics_core (1/3) metrics_core_tk4x #2200
alias: actual_core (2/3) actual_core_tk8x #2203
alias: configure_core (2/3) configure_core_tk8x #2204
alias: configinfo_core (2/3) configinfo_core_tk8x #2205
alias: current_configinfo_core (2/3) current_configinfo_core_tk8x #2206
alias: delete_core (2/3) delete_core_tk8x #2207
alias: latin_replace_core (2/3) latin_replace_core_tk8x #2208
alias: kanji_replace_core (2/3) kanji_replace_core_tk8x #2209
alias: measure_core (2/3) measure_core_tk8x #2210
alias: metrics_core (2/3) metrics_core_tk8x #2211
alias: actual_core (3/E) actual_core_tk8x #2214
alias: configure_core (3/E) configure_core_tk8x #2215
alias: configinfo_core (3/E) configinfo_core_tk8x #2216
alias: current_configinfo_core (3/E) current_configinfo_core_tk8x #2217
alias: delete_core (3/E) delete_core_tk8x #2218
alias: latin_replace_core (3/E) latin_replace_core_tk8x #2219
alias: kanji_replace_core (3/E) kanji_replace_core_tk8x #2220
alias: measure_core (3/E) measure_core_tk8x #2221
alias: metrics_core (3/E) metrics_core_tk8x #2222
  class: TkNamedFont#2232
inherits from
  TkFont   
has properties
class method: find / 1 #2234
class method: new / 2 #2242
method: initialize / 2 #2263
method: create_latinfont / 1 #2283
method: create_kanjifont / 1 #2286
method: create_compoundfont / 3 #2289
method: latin_font_id #2296
method: kanji_font_id #2299

Class Hierarchy

Object ( Builtin-Module )
TkFont#8, #2227
  TkNamedFont    #2232
DescendantFont ( TkFont ) — #146

Code

   1  #
   2  #  tk/font.rb - the class to treat fonts on Ruby/Tk
   3  #
   4  #                               by  Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
   5  #
   6  require 'tk'
   7 
   8  class TkFont
   9    include Tk
  10    extend TkCore
  11 
  12    TkCommandNames = ['font'.freeze].freeze
  13 
  14    (Tk_FontID = ["@font".freeze, "00000".taint]).instance_eval{
  15      @mutex = Mutex.new
  16      def mutex; @mutex; end
  17      freeze
  18    }
  19 
  20    Tk_FontNameTBL = TkCore::INTERP.create_table
  21    Tk_FontUseTBL  = TkCore::INTERP.create_table
  22 
  23    TkCore::INTERP.init_ip_env{ 
  24      Tk_FontNameTBL.mutex.synchronize{ Tk_FontNameTBL.clear }
  25      Tk_FontUseTBL.mutex.synchronize{ Tk_FontUseTBL.clear }
  26    }
  27 
  28    # option_type : default => string
  29    OptionType = Hash.new(?s)
  30    OptionType['size'] = ?n
  31    OptionType['pointadjust'] = ?n
  32    OptionType['underline'] = ?b
  33    OptionType['overstrike'] = ?b
  34 
  35    # metric_type : default => num_or_str
  36    MetricType = Hash.new(?n)
  37    MetricType['fixed'] = ?b
  38 
  39    # system font names
  40    SYSTEM_FONT_NAMES = []
  41    def SYSTEM_FONT_NAMES.add(font_names)
  42      (@mutex ||= Mutex.new).synchronize{
  43        self.replace(self | font_names.map{|name| name.to_s})
  44      }
  45    end
  46    def SYSTEM_FONT_NAMES.include?(name)
  47      (@mutex ||= Mutex.new).synchronize{
  48        super(name.to_s)
  49      }
  50    end
  51 
  52    # set default font
  53    case Tk::TK_VERSION
  54    when /^4\..*/
  55      DEFAULT_LATIN_FONT_NAME = 'a14'.freeze
  56      DEFAULT_KANJI_FONT_NAME = 'k14'.freeze
  57 
  58    when /^8\.[0-4]/
  59      if JAPANIZED_TK
  60        begin
  61          fontnames = tk_call('font', 'names')
  62          case fontnames
  63          when /defaultgui/
  64            # Tcl/Tk-JP for Windows
  65            ltn = 'defaultgui'
  66            knj = 'defaultgui'
  67          when /Mincho:Helvetica-Bold-12/
  68            # Tcl/Tk-JP for UNIX/X
  69            ltn, knj = tk_split_simplelist(tk_call('font', 'configure', 
  70                                                   'Mincho:Helvetica-Bold-12', 
  71                                                   '-compound'))
  72          else
  73            # unknown Tcl/Tk-JP
  74            #platform = tk_call('set', 'tcl_platform(platform)')
  75            platform = Tk::PLATFORM['platform']
  76            case platform
  77            when 'unix'
  78              ltn = {'family'=>'Helvetica'.freeze, 
  79                     'size'=>-12, 'weight'=>'bold'.freeze}
  80              #knj = 'k14'
  81              #knj = '-misc-fixed-medium-r-normal--14-*-*-*-c-*-jisx0208.1983-0'
  82              knj = '-*-fixed-bold-r-normal--12-*-*-*-c-*-jisx0208.1983-0'
  83            when 'windows'
  84              ltn = {'family'=>'MS Sans Serif'.freeze, 'size'=>8}
  85              knj = 'mincho'
  86            when 'macintosh'
  87              ltn = 'system'
  88              knj = 'mincho'
  89            else # unknown
  90              ltn = 'Helvetica'
  91              knj = 'mincho'
  92            end
  93          end
  94        rescue
  95          ltn = 'Helvetica'
  96          knj = 'mincho'
  97        end
  98 
  99      else # not JAPANIZED_TK
 100        begin
 101          #platform = tk_call('set', 'tcl_platform(platform)')
 102          platform = Tk::PLATFORM['platform']
 103          case platform
 104          when 'unix'
 105            ltn = {'family'=>'Helvetica'.freeze, 
 106                   'size'=>-12, 'weight'=>'bold'.freeze}
 107          when 'windows'
 108            ltn = {'family'=>'MS Sans Serif'.freeze, 'size'=>8}
 109          when 'macintosh'
 110            ltn = 'system'
 111          else # unknown
 112            ltn = 'Helvetica'
 113          end
 114        rescue
 115          ltn = 'Helvetica'
 116        end
 117 
 118        knj = ltn.dup
 119      end
 120 
 121      DEFAULT_LATIN_FONT_NAME = ltn.freeze
 122      DEFAULT_KANJI_FONT_NAME = knj.freeze
 123 
 124    when /^8\.[5-9]/, /^9\..*/
 125      if tk_call('font', 'names') =~ /\bTkDefaultFont\b/
 126        DEFAULT_LATIN_FONT_NAME = 'TkDefaultFont'.freeze
 127        DEFAULT_KANJI_FONT_NAME = 'TkDefaultFont'.freeze
 128      else
 129        DEFAULT_LATIN_FONT_NAME = 'Helvetica'.freeze
 130        DEFAULT_KANJI_FONT_NAME = 'mincho'.freeze
 131      end
 132 
 133    else # unknown version
 134      DEFAULT_LATIN_FONT_NAME = 'Helvetica'.freeze
 135      DEFAULT_KANJI_FONT_NAME = 'mincho'.freeze
 136 
 137    end
 138 
 139    if $DEBUG
 140      print "default latin font = "; p DEFAULT_LATIN_FONT_NAME
 141      print "default kanji font = "; p DEFAULT_KANJI_FONT_NAME
 142    end
 143 
 144 
 145    ###################################
 146    class DescendantFont
 147      def initialize(compound, type)
 148        unless compound.kind_of?(TkFont)
 149          fail ArgumentError, "a TkFont object is expected for the 1st argument"
 150        end
 151 
 152        @compound = compound
 153        case type
 154        when 'kanji', 'latin', 'ascii'
 155          @type = type
 156        when :kanji, :latin, :ascii
 157          @type = type.to_s
 158        else
 159          fail ArgumentError, "unknown type '#{type}'"
 160        end
 161      end
 162 
 163      def dup
 164        fail RuntimeError, "cannot dupulicate a descendant font"
 165      end
 166      def clone
 167        fail RuntimeError, "cannot clone a descendant font"
 168      end
 169 
 170      def to_eval
 171        @compound.__send__(@type + '_font_id')
 172      end
 173      def font
 174        @compound.__send__(@type + '_font_id')
 175      end
 176      alias font_id font
 177      alias name font
 178      alias to_s font
 179 
 180      def [](slot)
 181        @compound.__send__(@type + '_configinfo', slot)
 182      end
 183      def []=(slot, value)
 184        @compound.__send__(@type + '_configure', slot, value)
 185        value
 186      end
 187 
 188      def method_missing(id, *args)
 189        @compound.__send__(@type + '_' + id.id2name, *args)
 190      end
 191    end
 192 
 193 
 194    ###################################
 195    # class methods
 196    ###################################
 197    def TkFont.is_system_font?(fnt)
 198      # true  --> system font which is available on the current system
 199      # false --> not system font (or unknown system font)
 200      # nil   --> system font name, but not available on the current system
 201      fnt = fnt.to_s
 202      SYSTEM_FONT_NAMES.include?(fnt) && self.names.index(fnt) && true
 203    end
 204 
 205    def TkFont.actual(fnt, option=nil)
 206      fnt = '{}' if fnt == ''
 207      if fnt.kind_of?(TkFont)
 208       fnt.actual(option)
 209      else
 210        actual_core(fnt, nil, option)
 211      end
 212    end
 213    def TkFont.actual_hash(fnt, option=nil)
 214      Hash[TkFont.actual_hash(fnt, option)]
 215    end
 216 
 217    def TkFont.actual_displayof(fnt, win, option=nil)
 218      fnt = '{}' if fnt == ''
 219      if fnt.kind_of?(TkFont)
 220       fnt.actual_displayof(win, option)
 221      else
 222        win = '.' unless win
 223        actual_core(fnt, win, option)
 224      end
 225    end
 226    def TkFont.actual_hash_displayof(fnt, option=nil)
 227      Hash[TkFont.actual_hash_displayof(fnt, option)]
 228    end
 229 
 230    def TkFont.configure(fnt, slot, value=None)
 231      if fnt.kind_of?(TkFont)
 232        fnt.configure(fnt, slot, value)
 233      else
 234        configure_core(fnt, slot, value)
 235      end
 236      fnt
 237    end
 238 
 239    def TkFont.configinfo(fnt, slot=nil)
 240      if fnt.kind_of?(TkFont)
 241        fnt.configinfo(fnt, slot)
 242      else
 243        configinfo_core(fnt, slot)
 244      end
 245    end
 246 
 247    def TkFont.current_configinfo(fnt, slot=nil)
 248      if fnt.kind_of?(TkFont)
 249        fnt.current_configinfo(fnt, slot)
 250      else
 251        current_configinfo_core(fnt, slot)
 252      end
 253    end
 254 
 255    def TkFont.measure(fnt, text)
 256      fnt = '{}' if fnt == ''
 257      if fnt.kind_of?(TkFont)
 258        fnt.measure(text)
 259      else
 260        measure_core(fnt, nil, text)
 261      end
 262    end
 263 
 264    def TkFont.measure_displayof(fnt, win, text)
 265      fnt = '{}' if fnt == ''
 266      if fnt.kind_of?(TkFont)
 267        fnt.measure_displayof(win, text)
 268      else
 269        win = '.' unless win
 270        measure_core(fnt, win, text)
 271      end
 272    end
 273 
 274    def TkFont.metrics(fnt, option=nil)
 275      fnt = '{}' if fnt == ''
 276      if fnt.kind_of?(TkFont)
 277        fnt.metrics(option)
 278      else
 279        metrics_core(fnt, nil, option)
 280      end
 281    end
 282    def TkFont.metrics_hash(fnt, option=nil)
 283      if option
 284        val = TkFont.metrics(fnt, option)
 285        case TkFont::MetricsType[option.to_s]
 286        when ?n
 287          val = TkComm::num_or_str(val)
 288        when ?b
 289          val = TkComm::bool(val)
 290        else
 291          # do nothing
 292        end
 293        return val
 294      end
 295 
 296      h = Hash[TkFont.metrics(fnt)]
 297      h.keys.each{|k| 
 298        case TkFont::MetricsType[k.to_s]
 299        when ?n
 300          h[k] = TkComm::num_or_str(h[k])
 301        when ?b
 302          h[k] = TkComm::bool(h[k])
 303        else
 304          # do nothing
 305        end
 306      }
 307      h
 308    end
 309 
 310    def TkFont.metrics_displayof(fnt, win, option=nil)
 311      fnt = '{}' if fnt == ''
 312      if fnt.kind_of?(TkFont)
 313        font.metrics_displayof(win, option=nil)
 314      else
 315        win = '.' unless win
 316        metrics_core(fnt, win, option)
 317      end
 318    end
 319    def TkFont.metrics_hash_displayof(fnt, win, option=nil)
 320      if option
 321        val = TkFont.metrics_displayof(fnt, win, option)
 322        case TkFont::MetricsType[option.to_s]
 323        when ?n
 324          val = TkComm::num_or_str(val)
 325        when ?b
 326          val = TkComm::bool(val)
 327        else
 328          # do nothing
 329        end
 330        return val
 331      end
 332 
 333      h = Hash[TkFont.metrics_displayof(fnt, win, option)]
 334      h.keys.each{|k| 
 335        case TkFont::MetricsType[k.to_s]
 336        when ?n
 337          h[k] = TkComm::num_or_str(h[k])
 338        when ?b
 339          h[k] = TkComm::bool(h[k])
 340        else
 341          # do nothing
 342        end
 343      }
 344      h
 345    end
 346 
 347    def TkFont.families(win=nil)
 348      case (Tk::TK_VERSION)
 349      when /^4\..*/
 350        ['fixed']
 351 
 352      when /^8\..*/
 353        if win
 354          tk_split_simplelist(tk_call('font', 'families', '-displayof', win))
 355        else
 356          tk_split_simplelist(tk_call('font', 'families'))
 357        end
 358      end
 359    end
 360 
 361    def TkFont.names
 362      case (Tk::TK_VERSION)
 363      when /^4\..*/
 364        r = ['fixed']
 365        r += ['a14', 'k14'] if JAPANIZED_TK
 366        Tk_FontNameTBL.mutex.synchronize{
 367          Tk_FontNameTBL.each_value{|obj| r.push(obj)}
 368        }
 369        #r | []
 370        r.uniq
 371 
 372      when /^8\..*/
 373        tk_split_simplelist(tk_call('font', 'names'))
 374 
 375      end
 376    end
 377 
 378    def TkFont.create_copy(font)
 379      fail 'source-font must be a TkFont object' unless font.kind_of? TkFont
 380      if TkComm::GET_CONFIGINFOwoRES_AS_ARRAY
 381        keys = {}
 382        font.configinfo.each{|key,value| keys[key] = value }
 383        TkFont.new(font.latin_font_id, font.kanji_font_id, keys)
 384      else # ! TkComm::GET_CONFIGINFOwoRES_AS_ARRAY
 385        TkFont.new(font.latin_font_id, font.kanji_font_id, font.configinfo)
 386      end
 387    end
 388 
 389    def TkFont.get_obj(name)
 390      name = name.to_s
 391      if name =~ /^(@font[0-9]+)(|c|l|k)$/
 392        Tk_FontNameTBL.mutex.synchronize{
 393          Tk_FontNameTBL[$1]
 394        }
 395      else
 396        Tk_FontNameTBL.mutex.synchronize{
 397          Tk_FontNameTBL[name]
 398        }
 399      end
 400    end
 401 
 402    def TkFont.init_widget_font(pathname, *args)
 403      win, tag, key = pathname.split(';')
 404      key = 'font' if key == nil || key == ''
 405      path = [win, tag, key].join(';')
 406 
 407      case (Tk::TK_VERSION)
 408      when /^4\..*/
 409        regexp = /^-(|kanji)#{key} /
 410 
 411        conf_list = tk_split_simplelist(tk_call(*args)).
 412          find_all{|prop| prop =~ regexp}.
 413          collect{|prop| tk_split_simplelist(prop)}
 414 
 415        if conf_list.size == 0
 416          raise RuntimeError, "the widget may not support 'font' option"
 417        end
 418 
 419        args << {}
 420 
 421        ltn_key = "-#{key}"
 422        knj_key = "-kanji#{key}"
 423 
 424        ltn_info = conf_list.find{|conf| conf[0] == ltn_key}
 425        ltn = ltn_info[-1]
 426        ltn = nil if ltn == [] || ltn == ""
 427 
 428        knj_info = conf_list.find{|conf| conf[0] == knj_key}
 429        knj = knj_info[-1]
 430        knj = nil if knj == [] || knj == ""
 431 
 432        TkFont.new(ltn, knj).call_font_configure([path, key], *args)
 433 
 434      when /^8\.[0-4]/
 435        regexp = /^-#{key} /
 436 
 437        conf_list = tk_split_simplelist(tk_call(*args)).
 438          find_all{|prop| prop =~ regexp}.
 439          collect{|prop| tk_split_simplelist(prop)}
 440 
 441        if conf_list.size == 0
 442          raise RuntimeError, "the widget may not support 'font' option"
 443        end
 444 
 445        args << {}
 446 
 447        optkey = "-#{key}"
 448 
 449        info = conf_list.find{|conf| conf[0] == optkey}
 450        fnt = info[-1]
 451        fnt = nil if fnt == [] || fnt == ""
 452 
 453        unless fnt
 454          # create dummy
 455          # TkFont.new(nil, nil).call_font_configure([path, key], *args)
 456          dummy_fnt = TkFont.allocate
 457          dummy_fnt.instance_eval{ init_dummy_fontobj() }
 458          dummy_fnt
 459        else
 460          begin
 461            compound = tk_split_simplelist(
 462                Hash[*tk_split_simplelist(tk_call('font', 'configure', 
 463                                                  fnt))].collect{|k,v|
 464                  [k[1..-1], v]
 465                }.assoc('compound')[1])
 466          rescue
 467            compound = []
 468          end
 469          if compound == []
 470            if TkFont.is_system_font?(fnt)
 471              TkNamedFont.new(fnt).call_font_configure([path, key], *args)
 472            else
 473              TkFont.new(fnt).call_font_configure([path, key], *args)
 474            end
 475          else
 476            TkFont.new(compound[0], 
 477                       compound[1]).call_font_configure([path, key], *args)
 478          end
 479        end
 480 
 481      when /^8\.[5-9]/, /^9\..*/
 482        regexp = /^-#{key} /
 483 
 484        conf_list = tk_split_simplelist(tk_call(*args)).
 485          find_all{|prop| prop =~ regexp}.
 486          collect{|prop| tk_split_simplelist(prop)}
 487 
 488        if conf_list.size == 0
 489          raise RuntimeError, "the widget may not support 'font' option"
 490        end
 491 
 492        args << {}
 493 
 494        optkey = "-#{key}"
 495 
 496        info = conf_list.find{|conf| conf[0] == optkey}
 497        fnt = info[-1]
 498        fnt = nil if fnt == [] || fnt == ""
 499 
 500        unless fnt
 501          # create dummy
 502          # TkFont.new(nil, nil).call_font_configure([path, key], *args)
 503          dummy_fnt = TkFont.allocate
 504          dummy_fnt.instance_eval{ init_dummy_fontobj() }
 505          dummy_fnt
 506        else
 507          if TkFont.is_system_font?(fnt)
 508            TkNamedFont.new(fnt).call_font_configure([path, key], *args)
 509          else
 510            TkFont.new(fnt).call_font_configure([path, key], *args)
 511          end
 512        end
 513      end
 514    end
 515 
 516    def TkFont.used_on(path=nil)
 517      Tk_FontUseTBL.mutex.synchronize{
 518        if path
 519          Tk_FontUseTBL[path]
 520        else
 521          # Tk_FontUseTBL.values | []
 522          Tk_FontUseTBL.values.uniq
 523        end
 524      }
 525    end
 526 
 527    def TkFont.failsafe(font)
 528      begin
 529        if /^8\..*/ === Tk::TK_VERSION  && JAPANIZED_TK
 530          tk_call('font', 'failsafe', font)
 531        end
 532      rescue
 533      end
 534    end
 535 
 536    ###################################
 537    # instance methods
 538    ###################################
 539    private
 540    ###################################
 541    def init_dummy_fontobj
 542      Tk_FontID.mutex.synchronize{
 543        @id = Tk_FontID.join(TkCore::INTERP._ip_id_)
 544        Tk_FontID[1].succ!
 545      }
 546      Tk_FontNameTBL.mutex.synchronize{
 547        Tk_FontNameTBL[@id] = self
 548      }
 549 
 550      # @latin_desscendant = nil
 551      # @kanji_desscendant = nil
 552      @descendant = [nil, nil] # [latin, kanji]
 553 
 554      case (Tk::TK_VERSION)
 555      when /^4\..*/
 556        @latinfont = ""
 557        @kanjifont = ""
 558        if JAPANIZED_TK
 559          @compoundfont = [[@latinfont], [@kanjifont]]
 560          @fontslot = {'font'=>@latinfont, 'kanjifont'=>@kanjifont}
 561        else
 562          @compoundfont = @latinfont
 563          @fontslot = {'font'=>@latinfont}
 564        end
 565      else
 566        @latinfont = @id + 'l'
 567        @kanjifont = @id + 'k'
 568        @compoundfont = @id + 'c'
 569 
 570        if JAPANIZED_TK
 571          tk_call('font', 'create', @latinfont, '-charset', 'iso8859')
 572          tk_call('font', 'create', @kanjifont, '-charset', 'jisx0208.1983')
 573          tk_call('font', 'create', @compoundfont, 
 574                  '-compound', [@latinfont, @kanjifont])
 575        else
 576          tk_call('font', 'create', @latinfont)
 577          tk_call('font', 'create', @kanjifont)
 578          tk_call('font', 'create', @compoundfont)
 579        end
 580 
 581        @fontslot = {'font'=>@compoundfont}
 582      end
 583 
 584      self
 585    end
 586 
 587    def initialize(ltn=nil, knj=nil, keys=nil)
 588      ltn = '{}' if ltn == ''
 589      knj = '{}' if knj == ''
 590 
 591      Tk_FontID.mutex.synchronize{
 592        # @id = Tk_FontID.join('')
 593        @id = Tk_FontID.join(TkCore::INTERP._ip_id_)
 594        Tk_FontID[1].succ!
 595      }
 596      Tk_FontNameTBL.mutex.synchronize{
 597        Tk_FontNameTBL[@id] = self
 598      }
 599 
 600      # @latin_desscendant = nil
 601      # @kanji_desscendant = nil
 602      @descendant = [nil, nil] # [latin, kanji]
 603 
 604      # @latinfont = @id + 'l'
 605      # @kanjifont = @id + 'k'
 606      # @compoundfont = @id + 'c'
 607      # @fontslot = {}
 608 
 609      if knj.kind_of?(Hash) && !keys
 610        keys = knj
 611        knj = nil
 612      end
 613 
 614      # compound font check
 615      if Tk::TK_VERSION == '8.0' && JAPANIZED_TK
 616        begin
 617          compound = tk_split_simplelist(tk_call('font', 'configure', 
 618                                                 ltn, '-compound'))
 619          if knj == nil
 620            if compound != []
 621              ltn, knj = compound
 622            end
 623          else
 624            if compound != []
 625              ltn = compound[0]
 626            end
 627            compound = tk_split_simplelist(tk_call('font', 'configure', 
 628                                                   knj, '-compound'))
 629            if compound != []
 630              knj = compound[1]
 631            end
 632          end
 633        rescue
 634        end
 635      end
 636 
 637      if ltn
 638        if JAPANIZED_TK && !knj
 639          if Tk::TK_VERSION =~ /^4..*/
 640            knj = DEFAULT_KANJI_FONT_NAME
 641          else
 642            knj = ltn 
 643          end
 644        end
 645      else
 646        ltn = DEFAULT_LATIN_FONT_NAME
 647        knj = DEFAULT_KANJI_FONT_NAME if JAPANIZED_TK && !knj
 648      end
 649 
 650      create_compoundfont(ltn, knj, keys)
 651    end
 652 
 653    def initialize_copy(font)
 654      unless font.kind_of?(TkFont)
 655        fail TypeError, '"initialize_copy should take same class object'
 656      end
 657      if TkComm::GET_CONFIGINFOwoRES_AS_ARRAY
 658        keys = {}
 659        font.configinfo.each{|key,value| keys[key] = value }
 660        initialize(font.latin_font_id, font.kanji_font_id, keys)
 661      else # ! TkComm::GET_CONFIGINFOwoRES_AS_ARRAY
 662        initialize(font.latin_font_id, font.kanji_font_id, font.configinfo)
 663      end
 664    end
 665 
 666    def _get_font_info_from_hash(font)
 667      font = _symbolkey2str(font)
 668      foundry  = (info = font['foundry'] .to_s)?  info: '*'
 669      family   = (info = font['family']  .to_s)?  info: '*'
 670      weight   = (info = font['weight']  .to_s)?  info: '*'
 671      slant    = (info = font['slant']   .to_s)?  info: '*'
 672      swidth   = (info = font['swidth']  .to_s)?  info: '*'
 673      adstyle  = (info = font['adstyle'] .to_s)?  info: '*'
 674      pixels   = (info = font['pixels']  .to_s)?  info: '*'
 675      points   = (info = font['points']  .to_s)?  info: '*'
 676      resx     = (info = font['resx']    .to_s)?  info: '*'
 677      resy     = (info = font['resy']    .to_s)?  info: '*'
 678      space    = (info = font['space']   .to_s)?  info: '*'
 679      avgWidth = (info = font['avgWidth'].to_s)?  info: '*'
 680      charset  = (info = font['charset'] .to_s)?  info: '*'
 681      encoding = (info = font['encoding'].to_s)?  info: '*'
 682 
 683      [foundry, family, weight, slant, swidth, adstyle,
 684        pixels, points, resx, resy, space, avgWidth, charset, encoding]
 685    end
 686 
 687    def create_latinfont_tk4x(font)
 688      if font.kind_of? Hash
 689        @latinfont = '-' + _get_font_info_from_hash(font).join('-') + '-'
 690 
 691      elsif font.kind_of? Array
 692        finfo = {}
 693        finfo['family'] = font[0].to_s
 694        if font[1]
 695          fsize = font[1].to_s
 696          if fsize != '0' && fsize =~ /^(|\+|-)([0-9]+)$/
 697            if $1 == '-'
 698              finfo['pixels'] = $2
 699            else
 700              finfo['points'] = $2
 701            end
 702          else
 703            finfo['points'] = '13'
 704          end
 705        end
 706        font[2..-1].each{|style|
 707          case (style)
 708          when 'normal'
 709            finfo['weight'] = style
 710          when 'bold'
 711            finfo['weight'] = style
 712          when 'roman'
 713            finfo['slant'] = 'r'
 714          when 'italic'
 715            finfo['slant'] = 'i'
 716          end
 717        }
 718 
 719        @latinfont = '-' + _get_font_info_from_hash(finfo).join('-') + '-'
 720 
 721      elsif font.kind_of? TkFont
 722        @latinfont = font.latin_font
 723 
 724      else
 725        if font
 726          @latinfont = font
 727        else
 728          @latinfont = DEFAULT_LATIN_FONT_NAME
 729        end
 730 
 731      end
 732    end
 733 
 734    def create_kanjifont_tk4x(font)
 735      unless JAPANIZED_TK
 736        @kanjifont = ""
 737        return
 738      end
 739 
 740      if font.kind_of? Hash
 741        @kanjifont = '-' + _get_font_info_from_hash(font).join('-') + '-'
 742 
 743      elsif font.kind_of? Array
 744        finfo = {}
 745        finfo['family'] = font[0].to_s
 746        if font[1]
 747          fsize = font[1].to_s
 748          if fsize != '0' && fsize =~ /^(|\+|-)([0-9]+)$/
 749            if $1 == '-'
 750              finfo['pixels'] = $2
 751            else
 752              finfo['points'] = $2
 753            end
 754          else
 755            finfo['points'] = '13'
 756          end
 757        end
 758        font[2..-1].each{|style|
 759          case (style)
 760          when 'normal'
 761            finfo['weight'] = style
 762          when 'bold'
 763            finfo['weight'] = style
 764          when 'roman'
 765            finfo['slant'] = 'r'
 766          when 'italic'
 767            finfo['slant'] = 'i'
 768          end
 769        }
 770 
 771        @kanjifont = '-' + _get_font_info_from_hash(finfo).join('-') + '-'
 772      elsif font.kind_of? TkFont
 773        @kanjifont = font.kanji_font_id
 774      else
 775        if font
 776          @kanjifont = font
 777        else
 778          @kanjifont = DEFAULT_KANJI_FONT_NAME
 779        end
 780      end
 781    end
 782 
 783    def create_compoundfont_tk4x(ltn, knj, keys)
 784      create_latinfont(ltn)
 785      create_kanjifont(knj)
 786 
 787      if JAPANIZED_TK
 788        @compoundfont = [[@latinfont], [@kanjifont]]
 789        @fontslot = {'font'=>@latinfont, 'kanjifont'=>@kanjifont}
 790        # @fontslot.clear
 791        # @fontslot['font'] = @latinfont
 792        # @fontslot['kanjifont'] = @kanjifont
 793      else
 794        @compoundfont = @latinfont
 795        @fontslot = {'font'=>@latinfont}
 796        # @fontslot.clear
 797        # @fontslot['font'] = @latinfont
 798      end
 799    end
 800 
 801    def create_latinfont_tk8x(font)
 802      @latinfont = @id + 'l'
 803 
 804      if JAPANIZED_TK
 805        if font.kind_of? Hash
 806          if font[:charset] || font['charset']
 807            tk_call('font', 'create', @latinfont, *hash_kv(font))
 808          else
 809            tk_call('font', 'create', @latinfont, 
 810                    '-charset', 'iso8859', *hash_kv(font))
 811          end
 812        elsif font.kind_of? Array
 813          tk_call('font', 'create', @latinfont, '-copy', array2tk_list(font))
 814          tk_call('font', 'configure', @latinfont, '-charset', 'iso8859')
 815        elsif font.kind_of? TkFont
 816          tk_call('font', 'create', @latinfont, '-copy', font.latin_font)
 817        elsif font
 818          tk_call('font', 'create', @latinfont, '-copy', font, 
 819                  '-charset', 'iso8859')
 820        else
 821          tk_call('font', 'create', @latinfont, '-charset', 'iso8859')
 822        end
 823      else
 824        if font.kind_of? Hash
 825          tk_call('font', 'create', @latinfont, *hash_kv(font))
 826        else
 827          keys = {}
 828          if font.kind_of? Array
 829            actual_core(array2tk_list(font)).each{|key,val| keys[key] = val}
 830          elsif font.kind_of? TkFont
 831            actual_core(font.latin_font).each{|key,val| keys[key] = val}
 832          elsif font
 833            actual_core(font).each{|key,val| keys[key] = val}
 834          end
 835          tk_call('font', 'create', @latinfont, *hash_kv(keys))
 836        end
 837 
 838        if font && @compoundfont
 839          keys = {}
 840          actual_core(@latinfont).each{|key,val| keys[key] = val}
 841          tk_call('font', 'configure', @compoundfont, *hash_kv(keys))
 842        end
 843      end
 844    end
 845 
 846    def create_kanjifont_tk8x(font)
 847      @kanjifont = @id + 'k'
 848 
 849      if JAPANIZED_TK
 850        if font.kind_of? Hash
 851          if font[:charset] || font['charset']
 852            tk_call('font', 'create', @kanjifont, *hash_kv(font))
 853          else
 854            tk_call('font', 'create', @kanjifont, 
 855                    '-charset', 'jisx0208.1983', *hash_kv(font))
 856          end
 857        elsif font.kind_of? Array
 858          tk_call('font', 'create', @kanjifont, '-copy', array2tk_list(font))
 859          tk_call('font', 'configure', @kanjifont, '-charset', 'jisx0208.1983')
 860        elsif font.kind_of? TkFont
 861          tk_call('font', 'create', @kanjifont, '-copy', font.kanji_font_id)
 862        elsif font
 863          tk_call('font', 'create', @kanjifont, '-copy', font, 
 864                  '-charset', 'jisx0208.1983')
 865        else
 866          tk_call('font', 'create', @kanjifont, '-charset', 'jisx0208.1983')
 867        end
 868        # end of JAPANIZED_TK
 869 
 870      else
 871        if font.kind_of? Hash
 872          tk_call('font', 'create', @kanjifont, *hash_kv(font))
 873        else
 874          keys = {}
 875          if font.kind_of? Array
 876            actual_core(array2tk_list(font)).each{|key,val| keys[key] = val}
 877          elsif font.kind_of? TkFont
 878            actual_core(font.kanji_font_id).each{|key,val| keys[key] = val}
 879          elsif font
 880            actual_core(font).each{|key,val| keys[key] = val}
 881          end
 882          tk_call('font', 'create', @kanjifont, *hash_kv(keys))
 883        end
 884 
 885        if font && @compoundfont
 886          keys = {}
 887          actual_core(@kanjifont).each{|key,val| keys[key] = val}
 888          tk_call('font', 'configure', @compoundfont, *hash_kv(keys))
 889        end
 890      end
 891    end
 892 
 893    def create_compoundfont_tk8x(ltn, knj, keys)
 894      if knj
 895        create_latinfont(ltn)
 896        create_kanjifont(knj)
 897      else
 898        cfnt = ltn
 899        create_kanjifont(cfnt)
 900        create_latinfont(cfnt)
 901      end
 902 
 903      @compoundfont = @id + 'c'
 904 
 905      if JAPANIZED_TK
 906        unless keys
 907          keys = {}
 908        else
 909          keys = keys.dup
 910        end
 911        if (tk_call('font', 'configure', @latinfont, '-underline') == '1' &&
 912            tk_call('font', 'configure', @kanjifont, '-underline') == '1' &&
 913            !keys.key?('underline'))
 914          keys['underline'] = true
 915        end
 916        if (tk_call('font', 'configure', @latinfont, '-overstrike') == '1' &&
 917            tk_call('font', 'configure', @kanjifont, '-overstrike') == '1' &&
 918            !keys.key?('overstrike'))
 919          keys['overstrike'] = true
 920        end
 921 
 922        @fontslot = {'font'=>@compoundfont}
 923        # @fontslot['font'] = @compoundfont
 924        begin
 925          tk_call('font', 'create', @compoundfont, 
 926                  '-compound', [@latinfont, @kanjifont], *hash_kv(keys))
 927        rescue RuntimeError => e
 928          if ltn == knj
 929            if e.message =~ /kanji font .* specified/
 930              tk_call('font', 'delete', @latinfont)
 931              create_latinfont(DEFAULT_LATIN_FONT_NAME)
 932              opts = []
 933              Hash[*(tk_split_simplelist(tk_call('font', 'configure', 
 934                                                 @kanjifont)))].each{|k,v|
 935                case k
 936                when '-size', '-weight', '-slant', '-underline', '-overstrike'
 937                  opts << k << v
 938                end
 939              }
 940              tk_call('font', 'configure', @latinfont, *opts)
 941              tk_call('font', 'create', @compoundfont, 
 942                      '-compound', [@latinfont, @kanjifont], *hash_kv(keys))
 943 
 944            elsif e.message =~ /ascii font .* specified/
 945              tk_call('font', 'delete', @kanjifont)
 946              create_kanjifont(DEFAULT_KANJI_FONT_NAME)
 947              opts = []
 948              Hash[*(tk_split_simplelist(tk_call('font', 'configure', 
 949                                                 @latinfont)))].each{|k,v|
 950                case k
 951                when '-size', '-weight', '-slant', '-underline', '-overstrike'
 952                  opts << k << v
 953                end
 954              }
 955              tk_call('font', 'configure', @kanjifont, *opts)
 956              tk_call('font', 'create', @compoundfont, 
 957                      '-compound', [@latinfont, @kanjifont], *hash_kv(keys))
 958 
 959            else
 960              raise e
 961            end
 962          else
 963            raise e
 964          end
 965        end
 966      else
 967        tk_call('font', 'create', @compoundfont)
 968 
 969        latinkeys = {}
 970        begin
 971          actual_core(@latinfont).each{|key,val| latinkeys[key] = val}
 972        rescue
 973          latinkeys = {}
 974        end
 975        if latinkeys != {}
 976          tk_call('font', 'configure', @compoundfont, *hash_kv(latinkeys))
 977        end
 978 
 979        if knj
 980          compoundkeys = nil
 981          kanjikeys = {}
 982          begin
 983            actual_core(@kanjifont).each{|key,val| kanjikeys[key] = val}
 984          rescue
 985            kanjikeys = {}
 986          end
 987          if kanjikeys != {}
 988            tk_call('font', 'configure', @compoundfont, *hash_kv(kanjikeys))
 989          end
 990        end
 991 
 992        if cfnt
 993          if cfnt.kind_of?(Hash)
 994            compoundkeys = cfnt.dup
 995          else
 996            compoundkeys = {}
 997            actual_core(cfnt).each{|key,val| compoundkeys[key] = val}
 998          end
 999          compoundkeys.update(_symbolkey2str(keys))
1000          keys = compoundkeys
1001        end
1002 
1003        @fontslot = {'font'=>@compoundfont}
1004        # @fontslot['font'] = @compoundfont
1005        tk_call('font', 'configure', @compoundfont, *hash_kv(keys))
1006      end
1007    end
1008 
1009    ###################################
1010    public
1011    ###################################
1012    def inspect
1013      sprintf("#<%s:%0x:%s>", self.class.inspect, self.__id__, @compoundfont)
1014    end
1015 
1016    def method_missing(id, *args)
1017      name = id.id2name
1018      case args.length
1019      when 1
1020        if name[-1] == ?=
1021          configure name[0..-2], args[0]
1022          args[0]
1023        else
1024          configure name, args[0]
1025          self
1026        end
1027      when 0
1028        begin
1029          configinfo name
1030        rescue
1031          super(id, *args)
1032  #        fail NameError, "undefined local variable or method `#{name}' for #{self.to_s}", error_at
1033        end
1034      else
1035        super(id, *args)
1036  #      fail NameError, "undefined method `#{name}' for #{self.to_s}", error_at
1037      end
1038    end
1039 
1040    def call_font_configure(path, *args)
1041      if path.kind_of?(Array)
1042        # [path, optkey]
1043        win, tag = path[0].split(';')
1044        optkey = path[1].to_s
1045      else
1046        win, tag, optkey = path.split(';')
1047      end
1048 
1049      fontslot = _symbolkey2str(@fontslot)
1050      if optkey && optkey != ""
1051        ltn = fontslot.delete('font')
1052        knj = fontslot.delete('kanjifont')
1053        fontslot[optkey] = ltn if ltn
1054        fontslot["kanji#{optkey}"] = knj if knj
1055      end
1056 
1057      keys = _symbolkey2str(args.pop).update(fontslot)
1058      args.concat(hash_kv(keys))
1059      begin
1060        tk_call(*args)
1061      rescue => e
1062        unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__
1063          fail e
1064        end
1065      end
1066      Tk_FontUseTBL.mutex.synchronize{
1067        Tk_FontUseTBL[[win, tag, optkey].join(';')] = self
1068      }
1069      self
1070    end
1071 
1072    def used
1073      ret = []
1074      table = nil
1075      Tk_FontUseTBL.mutex.synchronize{
1076        table = Tk_FontUseTBL.clone # to avoid deadlock
1077      }
1078      table.each{|key,value|
1079        next unless self == value
1080        if key.include?(';')
1081          win, tag, optkey = key.split(';')
1082          winobj = tk_tcl2ruby(win)
1083          #if winobj.kind_of? TkText
1084          if winobj.kind_of?(TkText) || winobj.kind_of?(Tk::Text)
1085            if optkey
1086              ret.push([winobj, winobj.tagid2obj(tag), optkey])
1087            else
1088              ret.push([winobj, winobj.tagid2obj(tag)])
1089            end
1090          #elsif winobj.kind_of? TkCanvas
1091          elsif winobj.kind_of?(TkCanvas) || winobj.kind_of?(Tk::Canvas)
1092            if (tagobj = TkcTag.id2obj(winobj, tag)).kind_of? TkcTag
1093              if optkey
1094                ret.push([winobj, tagobj, optkey])
1095              else
1096                ret.push([winobj, tagobj])
1097              end
1098            elsif (tagobj = TkcItem.id2obj(winobj, tag)).kind_of? TkcItem
1099              if optkey
1100                ret.push([winobj, tagobj, optkey])
1101              else
1102                ret.push([winobj, tagobj])
1103              end
1104            else
1105              if optkey
1106                ret.push([winobj, tag, optkey])
1107              else
1108                ret.push([winobj, tag])
1109              end
1110            end
1111          #elsif winobj.kind_of? TkMenu
1112          elsif winobj.kind_of?(TkMenu) || winobj.kind_of?(Tk::Menu)
1113            if optkey
1114              ret.push([winobj, tag, optkey])
1115            else
1116              ret.push([winobj, tag])
1117            end
1118          else
1119            if optkey
1120              ret.push([win, tag, optkey])
1121            else
1122              ret.push([win, tag])
1123            end
1124          end
1125        else
1126          ret.push(tk_tcl2ruby(key))
1127        end
1128      }
1129      ret
1130    end
1131 
1132    def id
1133      @id
1134    end
1135 
1136    def to_eval
1137      font
1138    end
1139 
1140    def font
1141      @compoundfont
1142    end
1143    alias font_id font
1144    alias name font
1145    alias to_s font
1146 
1147    def latin_font_id
1148      @latinfont
1149    end
1150 
1151    def latin_font
1152      # @latinfont
1153      if @descendant[0] # [0] -> latin
1154        @descendant[0]
1155      else
1156        @descendant[0] = DescendantFont.new(self, 'latin')
1157      end
1158  =begin
1159      if @latin_descendant
1160        @latin_descendant
1161      else
1162        @latin_descendant = DescendantFont.new(self, 'latin')
1163      end
1164  =end
1165    end
1166    alias latinfont latin_font
1167 
1168    def kanji_font_id
1169      @kanjifont
1170    end
1171 
1172    def kanji_font
1173      # @kanjifont
1174      if @descendant[1] # [1] -> kanji
1175        @descendant[1]
1176      else
1177        @descendant[1] = DescendantFont.new(self, 'kanji')
1178      end
1179  =begin
1180      if @kanji_descendant
1181        @kanji_descendant
1182      else
1183        @kanji_descendant = DescendantFont.new(self, 'kanji')
1184      end
1185  =end
1186    end
1187    alias kanjifont kanji_font
1188 
1189    def actual(option=nil)
1190      actual_core(@compoundfont, nil, option)
1191    end
1192    def actual_hash(option=nil)
1193      Hash[actual(option)]
1194    end
1195 
1196    def actual_displayof(win, option=nil)
1197      win = '.' unless win
1198      actual_core(@compoundfont, win, option)
1199    end
1200    def actual_hash_displayof(win, option=nil)
1201      Hash[actual_displayof(win, option)]
1202    end
1203 
1204    def latin_actual(option=nil)
1205      if @latinfont == nil
1206        actual_core(@compoundfont, nil, option) # use @compoundfont
1207      else
1208        actual_core(@latinfont, nil, option)
1209      end
1210    end
1211    def latin_actual_hash(option=nil)
1212      Hash[latin_actual(option)]
1213    end
1214 
1215    def latin_actual_displayof(win, option=nil)
1216      win = '.' unless win
1217      if @latinfont == nil
1218        actual_core(@compoundfont, win, option) # use @compoundfont
1219      else
1220        actual_core(@latinfont, win, option)
1221      end
1222    end
1223    def latin_actual_hash_displayof(win, option=nil)
1224      Hash[latin_actual_displayof(win, option)]
1225    end
1226 
1227    def kanji_actual(option=nil)
1228      #if JAPANIZED_TK
1229      if @kanjifont == nil
1230        actual_core(@compoundfont, nil, option) # use @compoundfont
1231      elsif @kanjifont != ""
1232        actual_core(@kanjifont, nil, option)
1233      else
1234        actual_core_tk4x(nil, nil, option)
1235      end
1236    end
1237    def kanji_actual_hash(option=nil)
1238      Hash[kanji_actual(option)]
1239    end
1240 
1241    def kanji_actual_displayof(win, option=nil)
1242      #if JAPANIZED_TK
1243      if @kanjifont == nil
1244        actual_core(@compoundfont, nil, option) # use @compoundfont
1245      elsif @kanjifont != ""
1246        win = '.' unless win
1247        actual_core(@kanjifont, win, option)
1248      else
1249        actual_core_tk4x(nil, win, option)
1250      end
1251    end
1252    def kanji_actual_hash_displayof(win, option=nil)
1253      Hash[kanji_actual_displayof(win, option)]
1254    end
1255 
1256    def [](slot)
1257      configinfo slot
1258    end
1259 
1260    def []=(slot, val)
1261      configure slot, val
1262      val
1263    end
1264 
1265    def configure(slot, value=None)
1266      configure_core(@compoundfont, slot, value)
1267      self
1268    end
1269 
1270    def configinfo(slot=nil)
1271      configinfo_core(@compoundfont, slot)
1272    end
1273 
1274    def current_configinfo(slot=nil)
1275      current_configinfo_core(@compoundfont, slot)
1276    end
1277 
1278    def delete
1279      delete_core
1280    end
1281 
1282    def latin_configure(slot, value=None)
1283      if JAPANIZED_TK
1284        configure_core(@latinfont, slot, value)
1285      else
1286        configure(slot, value)
1287      end
1288      self
1289    end
1290 
1291    def latin_configinfo(slot=nil)
1292      if JAPANIZED_TK
1293        configinfo_core(@latinfont, slot)
1294      else
1295        configinfo(slot)
1296      end
1297    end
1298    def latin_current_configinfo(slot=nil)
1299      Hash[latin_configinfo(slot)]
1300    end
1301 
1302    def kanji_configure(slot, value=None)
1303      #if JAPANIZED_TK
1304      if @kanjifont == nil
1305        configure_core(@compoundfont, slot, value) # use @compoundfont
1306      elsif @kanjifont != ""
1307        configure_core(@kanjifont, slot, value)
1308        configure('size'=>configinfo('size')) # to reflect new configuration
1309      else
1310        #""
1311        configure(slot, value)
1312      end
1313      self
1314    end
1315 
1316    def kanji_configinfo(slot=nil)
1317      #if JAPANIZED_TK
1318      if @kanjifont == nil
1319        configure_core(@compoundfont, slot) # use @compoundfont
1320      elsif @kanjifont != ""
1321        configinfo_core(@kanjifont, slot)
1322      else
1323        #[]
1324        configinfo(slot)
1325      end
1326    end
1327    def kanji_current_configinfo(slot=nil)
1328      Hash[kanji_configinfo(slot)]
1329    end
1330 
1331    def replace(ltn, knj=None)
1332      knj = ltn if knj == None
1333      latin_replace(ltn)
1334      kanji_replace(knj)
1335      self
1336    end
1337 
1338    def latin_replace(ltn)
1339      if @latinfont
1340        latin_replace_core(ltn)
1341        reset_pointadjust
1342      else
1343        # not compound font -> copy properties of ltn
1344        latinkeys = {}
1345        begin
1346          actual_core(ltn).each{|key,val| latinkeys[key] = val}
1347        rescue
1348          latinkeys = {}
1349        end
1350        begin
1351          tk_call('font', 'configure', @compoundfont, *hash_kv(latinkeys))
1352        rescue
1353          # not exist? (deleted?) -> create font
1354          tk_call('font', 'create', @compoundfont, *hash_kv(latinkeys))
1355        end
1356      end
1357 
1358      self
1359    end
1360 
1361    def kanji_replace(knj)
1362      return self unless @kanjifont  # ignore
1363      kanji_replace_core(knj)
1364      reset_pointadjust
1365      self
1366    end
1367 
1368    def measure(text)
1369      measure_core(@compoundfont, nil, text)
1370    end
1371 
1372    def measure_displayof(win, text)
1373      win = '.' unless win
1374      measure_core(@compoundfont, win, text)
1375    end
1376 
1377    def metrics(option=nil)
1378      metrics_core(@compoundfont, nil, option)
1379    end
1380    def metrics_hash(option=nil)
1381      if option
1382        val = metrics(option)
1383        case TkFont::MetricsType[option.to_s]
1384        when ?n
1385          val = TkComm::num_or_str(val)
1386        when ?b
1387          val = TkComm::bool(val)
1388        else
1389          # do nothing
1390        end
1391        return val
1392      end
1393 
1394      h = Hash[metrics(option)]
1395      h.keys.each{|k| 
1396        case TkFont::MetricsType[k.to_s]
1397        when ?n
1398          h[k] = TkComm::num_or_str(h[k])
1399        when ?b
1400          h[k] = TkComm::bool(h[k])
1401        else
1402          # do nothing
1403        end
1404      }
1405      h
1406    end
1407 
1408    def metrics_displayof(win, option=nil)
1409      win = '.' unless win
1410      metrics_core(@compoundfont, win, option)
1411    end
1412    def metrics_hash_displayof(win, option=nil)
1413      if option
1414        val = metrics_displayof(win, option)
1415        case TkFont::MetricsType[option.to_s]
1416        when ?n
1417          val = TkComm::num_or_str(val)
1418        when ?b
1419          val = TkComm::bool(val)
1420        else
1421          # do nothing
1422        end
1423        return val
1424      end
1425 
1426      h = Hash[metrics_displayof(win, option)]
1427      h.keys.each{|k| 
1428        case TkFont::MetricsType[k.to_s]
1429        when ?n
1430          h[k] = TkComm::num_or_str(h[k])
1431        when ?b
1432          h[k] = TkComm::bool(h[k])
1433        else
1434          # do nothing
1435        end
1436      }
1437      h
1438    end
1439 
1440    def latin_metrics(option=nil)
1441      if @latinfont == nil
1442        metrics_core(@compoundfont, nil, option) # use @compoundfont
1443      else
1444        metrics_core(@latinfont, nil, option)
1445      end
1446    end
1447    def latin_metrics_hash(option=nil)
1448      if option
1449        val = latin_metrics(option)
1450        case TkFont::MetricsType[option.to_s]
1451        when ?n
1452          val = TkComm::num_or_str(val)
1453        when ?b
1454          val = TkComm::bool(val)
1455        else
1456          # do nothing
1457        end
1458        return val
1459      end
1460 
1461      h = Hash[latin_metrics(option)]
1462      h.keys.each{|k| 
1463        case TkFont::MetricsType[k.to_s]
1464        when ?n
1465          h[k] = TkComm::num_or_str(h[k])
1466        when ?b
1467          h[k] = TkComm::bool(h[k])
1468        else
1469          # do nothing
1470        end
1471      }
1472      h
1473    end
1474 
1475    def latin_metrics_displayof(win, option=nil)
1476      win = '.' unless win
1477      if @latinfont == nil
1478        metrics_core(@compoundfont, win, option) # use @compoundfont
1479      else
1480        metrics_core(@latinfont, win, option)
1481      end
1482    end
1483    def latin_metrics_hash_displayof(win, option=nil)
1484      if option
1485        val = latin_metrics_displayof(win, option)
1486        case TkFont::MetricsType[option.to_s]
1487        when ?n
1488          val = TkComm::num_or_str(val)
1489        when ?b
1490          val = TkComm::bool(val)
1491        else
1492          # do nothing
1493        end
1494        return val
1495      end
1496 
1497      h = Hash[latin_metrics_displayof(win, option)]
1498      h.keys.each{|k| 
1499        case TkFont::MetricsType[k.to_s]
1500        when ?n
1501          h[k] = TkComm::num_or_str(h[k])
1502        when ?b
1503          h[k] = TkComm::bool(h[k])
1504        else
1505          # do nothing
1506        end
1507      }
1508      h
1509    end
1510 
1511    def kanji_metrics(option=nil)
1512      if @latinfont == nil
1513        metrics_core(@compoundfont, nil, option) # use @compoundfont
1514      elsif JAPANIZED_TK
1515        metrics_core(@kanjifont, nil, option)
1516      else
1517        metrics_core_tk4x(nil, nil, option)
1518      end
1519    end
1520    def kanji_metrics_hash(option=nil)
1521      if option
1522        val = kanji_metrics(option)
1523        case TkFont::MetricsType[option.to_s]
1524        when ?n
1525          val = TkComm::num_or_str(val)
1526        when ?b
1527          val = TkComm::bool(val)
1528        else
1529          # do nothing
1530        end
1531        return val
1532      end
1533 
1534      h = Hash[kanji_metrics(option)]
1535      h.keys.each{|k| 
1536        case TkFont::MetricsType[k.to_s]
1537        when ?n
1538          h[k] = TkComm::num_or_str(h[k])
1539        when ?b
1540          h[k] = TkComm::bool(h[k])
1541        else
1542          # do nothing
1543        end
1544      }
1545      h
1546    end
1547 
1548    def kanji_metrics_displayof(win, option=nil)
1549      win = '.' unless win
1550      if @latinfont == nil
1551        metrics_core(@compoundfont, win, option) # use @compoundfont
1552      elsif JAPANIZED_TK
1553        metrics_core(@kanjifont, win, option)
1554      else
1555        metrics_core_tk4x(nil, win, option)
1556      end
1557    end
1558    def kanji_metrics_hash_displayof(win, option=nil)
1559      if option
1560        val = kanji_metrics_displayof(win, option)
1561        case TkFont::MetricsType[option.to_s]
1562        when ?n
1563          val = TkComm::num_or_str(val)
1564        when ?b
1565          val = TkComm::bool(val)
1566        else
1567          # do nothing
1568        end
1569        return val
1570      end
1571 
1572      h = Hash[kanji_metrics_displayof(win, option)]
1573      h.keys.each{|k| 
1574        case TkFont::MetricsType[k.to_s]
1575        when ?n
1576          h[k] = TkComm::num_or_str(h[k])
1577        when ?b
1578          h[k] = TkComm::bool(h[k])
1579        else
1580          # do nothing
1581        end
1582      }
1583      h
1584    end
1585 
1586    def reset_pointadjust
1587      begin
1588        if /^8\..*/ === Tk::TK_VERSION  && JAPANIZED_TK
1589          configure('pointadjust' => latin_actual.assoc('size')[1].to_f / 
1590                                        kanji_actual.assoc('size')[1].to_f )
1591        end
1592      rescue
1593      end
1594      self
1595    end
1596 
1597    ###################################
1598    # private alias
1599    ###################################
1600    case (Tk::TK_VERSION)
1601    when /^4\..*/
1602      alias create_latinfont        create_latinfont_tk4x
1603      alias create_kanjifont        create_kanjifont_tk4x
1604      alias create_compoundfont     create_compoundfont_tk4x
1605 
1606    when /^8\.[0-5]/
1607      alias create_latinfont        create_latinfont_tk8x
1608      alias create_kanjifont        create_kanjifont_tk8x
1609      alias create_compoundfont     create_compoundfont_tk8x
1610 
1611    else
1612      alias create_latinfont        create_latinfont_tk8x
1613      alias create_kanjifont        create_kanjifont_tk8x
1614      alias create_compoundfont     create_compoundfont_tk8x
1615 
1616    end
1617 
1618    ###################################
1619    # public alias
1620    ###################################
1621    alias ascii_font             latin_font
1622    alias asciifont              latinfont
1623    alias create_asciifont       create_latinfont
1624    alias ascii_actual           latin_actual
1625    alias ascii_actual_displayof latin_actual_displayof
1626    alias ascii_configure        latin_configure
1627    alias ascii_configinfo       latin_configinfo
1628    alias ascii_replace          latin_replace
1629    alias ascii_metrics          latin_metrics
1630 
1631    ###################################
1632  =begin
1633    def dup
1634      TkFont.new(self)
1635    end
1636    def clone
1637      TkFont.new(self)
1638    end
1639  =end
1640  end
1641 
1642  module TkFont::CoreMethods
1643    include Tk
1644    extend TkCore
1645 
1646    private
1647 
1648    def actual_core_tk4x(font, win=nil, option=nil)
1649      # dummy
1650      if option == 'pointadjust' || option == :pointadjust
1651          1.0
1652      elsif option
1653        case TkFont::OptionType[option.to_s]
1654        when ?n
1655          0
1656        when ?b
1657          false
1658        else
1659          ''
1660        end
1661      else
1662        [['family',''], ['size',0], ['weight',''], ['slant',''], 
1663          ['underline',false], ['overstrike',false], ['charset',''], 
1664          ['pointadjust',0]]
1665      end
1666    end
1667 
1668    def actual_core_tk8x(font, win=nil, option=nil)
1669      font = '{}' if font == ''
1670 
1671      if option == 'compound' || option == :compound
1672        ""
1673      elsif option
1674        if win
1675          val = tk_call('font', 'actual', font, 
1676                        "-displayof", win, "-#{option}")
1677        else
1678          val = tk_call('font', 'actual', font, "-#{option}")
1679        end
1680        case TkFont::OptionType[option.to_s]
1681        when ?n
1682          num_or_str(val)
1683        when ?b
1684          bool(val)
1685        else
1686          val
1687        end
1688      else
1689        l = tk_split_simplelist(if win
1690                                   tk_call('font', 'actual', font, 
1691                                                       "-displayof", win)
1692                                else
1693                                   tk_call('font', 'actual', font)
1694                                end)
1695        r = []
1696        while key=l.shift
1697          if key == '-compound'
1698            l.shift
1699          else
1700            key = key[1..-1]
1701            val = l.shift
1702            case TkFont::OptionType[key]
1703            when ?n
1704              r.push [key, num_or_str(val)]
1705            when ?b
1706              r.push [key, bool(val)]
1707            else
1708              r.push [key, val]
1709            end
1710          end
1711        end
1712        r
1713      end
1714    end
1715 
1716    def configure_core_tk4x(font, slot, value=None)
1717      #""
1718      self
1719    end
1720 
1721    def configinfo_core_tk4x(font, option=nil)
1722      # dummy
1723      if TkComm::GET_CONFIGINFOwoRES_AS_ARRAY
1724        if option == 'pointadjust' || option == :pointadjust
1725          1.0
1726        elsif option
1727          case TkFont::OptionType[option.to_s]
1728          when ?n
1729            0
1730          when ?b
1731            false
1732          else
1733            ''
1734          end
1735        else
1736          [['family',''], ['size',0], ['weight',''], ['slant',''], 
1737            ['underline',false], ['overstrike',false], ['charset',''], 
1738            ['pointadjust',1.0]]
1739        end
1740      else # ! TkComm::GET_CONFIGINFOwoRES_AS_ARRAY
1741        current_configinfo_core_tk4x(font, option)
1742      end
1743    end
1744 
1745    def current_configinfo_core_tk4x(font, option=nil)
1746      if option
1747        case TkFont::OptionType[option.to_s]
1748        when ?n
1749          0
1750        when ?b
1751          false
1752        else
1753          ''
1754        end
1755      else
1756        {'family'=>'', 'size'=>0, 'weight'=>'', 'slant'=>'', 
1757          'underline'=>false, 'overstrike'=>false, 
1758          'charset'=>false, 'pointadjust'=>1.0}
1759      end
1760    end
1761 
1762    def configure_core_tk8x(font, slot, value=None)
1763      if JAPANIZED_TK
1764        begin
1765          padjust = tk_call('font', 'configure', font, '-pointadjust')
1766        rescue
1767          padjust = nil
1768        end
1769      else
1770        padjust = nil
1771      end
1772      if slot.kind_of? Hash
1773        if JAPANIZED_TK && (slot.key?('family') || slot.key?(:family))
1774          slot = _symbolkey2str(slot)
1775          configure_core_tk8x(font, 'family', slot.delete('family'))
1776        end
1777 
1778        if ((slot.key?('size') || slot.key?(:size)) && 
1779            padjust && !slot.key?('pointadjust') && !slot.key?(:pointadjust))
1780          tk_call('font', 'configure', font, 
1781                  '-pointadjust', padjust, *hash_kv(slot))
1782        else
1783          tk_call('font', 'configure', font, *hash_kv(slot))
1784        end
1785      elsif (slot == 'size' || slot == :size) && padjust != nil
1786        tk_call('font', 'configure', font, 
1787                "-#{slot}", value, '-pointadjust', padjust)
1788      elsif JAPANIZED_TK && (slot == 'family' || slot == :family)
1789        # coumpund font?
1790        begin
1791          compound = tk_split_simplelist(tk_call('font', 'configure', 
1792                                                 font, '-compound'))
1793        rescue
1794          tk_call('font', 'configure', font, '-family', value)
1795          return self
1796        end
1797        if compound == []
1798          tk_call('font', 'configure', font, '-family', value)
1799          return self
1800        end
1801        ltn, knj = compound
1802 
1803        lfnt = tk_call('font', 'create', '-copy', ltn)
1804        begin
1805          tk_call('font', 'configure', lfnt, '-family', value)
1806          latin_replace_core_tk8x(lfnt)
1807        rescue RuntimeError => e
1808          fail e if $DEBUG
1809        ensure
1810          tk_call('font', 'delete', lfnt) if lfnt != ''
1811        end
1812 
1813        kfnt = tk_call('font', 'create', '-copy', knj)
1814        begin
1815          tk_call('font', 'configure', kfnt, '-family', value)
1816          kanji_replace_core_tk8x(lfnt)
1817        rescue RuntimeError => e
1818          fail e if $DEBUG
1819        ensure
1820          tk_call('font', 'delete', kfnt) if kfnt != ''
1821        end
1822        
1823      else
1824        tk_call('font', 'configure', font, "-#{slot}", value)
1825      end
1826      self
1827    end
1828 
1829    def configinfo_core_tk8x(font, option=nil)
1830      if TkComm::GET_CONFIGINFOwoRES_AS_ARRAY
1831        if option == 'compound' || option == :compound
1832          ""
1833        elsif option
1834          val = tk_call('font', 'configure', font, "-#{option}")
1835          case TkFont::OptionType[option.to_s]
1836          when ?n
1837            num_or_str(val)
1838          when ?b
1839            bool(val)
1840          else
1841            val
1842          end
1843        else
1844          l = tk_split_simplelist(tk_call('font', 'configure', font))
1845          r = []
1846          while key=l.shift
1847            if key == '-compound'
1848              l.shift
1849            else
1850              key = key[1..-1]
1851              val = l.shift
1852              case TkFont::OptionType[key]
1853              when ?n
1854                r.push [key, num_or_str(val)]
1855              when ?b
1856                r.push [key, bool(val)]
1857              else
1858                r.push [key, val]
1859              end
1860            end
1861          end
1862          r
1863        end
1864      else # ! TkComm::GET_CONFIGINFOwoRES_AS_ARRAY
1865        current_configinfo_core_tk8x(font, option)
1866      end
1867    end
1868 
1869    def current_configinfo_core_tk8x(font, option=nil)
1870      if option == 'compound'
1871        ""
1872      elsif option
1873        val = tk_call('font', 'configure', font, "-#{option}")
1874        case TkFont::OptionType[option.to_s]
1875        when ?n
1876          num_or_str(val)
1877        when ?b
1878          bool(val)
1879        else
1880          val
1881        end
1882      else
1883        l = tk_split_simplelist(tk_call('font', 'configure', font))
1884        h = {}
1885        while key=l.shift
1886          if key == '-compound'
1887            l.shift
1888          else
1889            key = key[1..-1]
1890            val = l.shift
1891            case TkFont::OptionType[key]
1892            when ?n
1893              h[key] = num_or_str(val)
1894            when ?b
1895              h[key] = bool(val)
1896            else
1897              h[key] = val
1898            end
1899          end
1900        end
1901        h
1902      end
1903    end
1904 
1905    def delete_core_tk4x
1906      TkFont::Tk_FontNameTBL.mutex.synchronize{
1907        TkFont::Tk_FontNameTBL.delete(@id)
1908      }
1909      TkFont::Tk_FontUseTBL.mutex.synchronize{
1910        TkFont::Tk_FontUseTBL.delete_if{|key,value| value == self}
1911      }
1912    end
1913 
1914    def delete_core_tk8x
1915      begin
1916        tk_call('font', 'delete', @latinfont) if @latinfont
1917      rescue
1918      end
1919      begin
1920        tk_call('font', 'delete', @kanjifont) if @kanjifont
1921      rescue
1922      end
1923      begin
1924        tk_call('font', 'delete', @compoundfont) if @compoundfont
1925      rescue
1926      end
1927      TkFont::Tk_FontNameTBL.mutex.synchronize{
1928        TkFont::Tk_FontNameTBL.delete(@id)
1929      }
1930      TkFont::Tk_FontUseTBL.mutex.synchronize{
1931        TkFont::Tk_FontUseTBL.delete_if{|key,value| value == self}
1932      }
1933    end
1934 
1935    def latin_replace_core_tk4x(ltn)
1936      create_latinfont_tk4x(ltn)
1937      @compoundfont[0] = [@latinfont] if JAPANIZED_TK
1938      @fontslot['font'] = @latinfont
1939      table = nil
1940      TkFont::Tk_FontUseTBL.mutex.synchronize{
1941        table = TkFont::Tk_FontUseTBL.clone
1942      }
1943      table.each{|w, fobj|
1944        if self == fobj
1945          begin
1946            if w.include?(';')
1947              win, tag, optkey = w.split(';')
1948              optkey = 'font' if optkey == nil || optkey == ''
1949              winobj = tk_tcl2ruby(win)
1950  #           winobj.tagfont_configure(tag, {'font'=>@latinfont})
1951              #if winobj.kind_of? TkText
1952              if winobj.kind_of?(TkText) || winobj.kind_of?(Tk::Text)
1953                tk_call(win, 'tag', 'configure', tag, "-#{optkey}", @latinfont)
1954              #elsif winobj.kind_of? TkCanvas
1955              elsif winobj.kind_of?(TkCanvas) || winobj.kind_of?(Tk::Canvas)
1956                tk_call(win, 'itemconfigure', tag, "-#{optkey}", @latinfont)
1957              #elsif winobj.kind_of? TkMenu
1958              elsif winobj.kind_of?(TkMenu) || winobj.kind_of?(Tk::Menu)
1959                tk_call(win, 'entryconfigure', tag, "-#{optkey}", @latinfont)
1960              else
1961                raise RuntimeError, "unknown widget type"
1962              end
1963            else
1964  #           tk_tcl2ruby(w).font_configure('font'=>@latinfont)
1965              tk_call(w, 'configure', '-font', @latinfont)
1966            end
1967          rescue
1968            TkFont::Tk_FontUseTBL.mutex.synchronize{
1969              TkFont::Tk_FontUseTBL.delete(w)
1970            }
1971          end
1972        end
1973      }
1974      self
1975    end
1976 
1977    def kanji_replace_core_tk4x(knj)
1978      return self unless JAPANIZED_TK
1979 
1980      create_kanjifont_tk4x(knj)
1981      @compoundfont[1] = [@kanjifont]
1982      @fontslot['kanjifont'] = @kanjifont
1983      table = nil
1984      TkFont::Tk_FontUseTBL.mutex.synchronize{
1985        table = TkFont::Tk_FontUseTBL.clone
1986      }
1987      table.dup.each{|w, fobj|
1988        if self == fobj
1989          begin
1990            if w.include?(';')
1991              win, tag, optkey = w.split(';')
1992              optkey = 'kanjifont' unless optkey
1993              winobj = tk_tcl2ruby(win)
1994  #           winobj.tagfont_configure(tag, {'kanjifont'=>@kanjifont})
1995              #if winobj.kind_of? TkText
1996              if winobj.kind_of?(TkText) || winobj.kind_of?(Tk::Text)
1997                tk_call(win, 'tag', 'configure', tag, "-#{optkey}", @kanjifont)
1998              #elsif winobj.kind_of? TkCanvas
1999              elsif winobj.kind_of?(TkCanvas) || winobj.kind_of?(Tk::Canvas)
2000                tk_call(win, 'itemconfigure', tag, "-#{optkey}", @kanjifont)
2001              #elsif winobj.kind_of? TkMenu
2002              elsif winobj.kind_of?(TkMenu) || winobj.kind_of?(Tk::Menu)
2003                tk_call(win, 'entryconfigure', tag, "-#{optkey}", @latinfont)
2004              else
2005                raise RuntimeError, "unknown widget type"
2006              end
2007            else
2008  #           tk_tcl2ruby(w).font_configure('kanjifont'=>@kanjifont)
2009              tk_call(w, 'configure', '-kanjifont', @kanjifont)
2010            end
2011          rescue
2012            Tk_FontUseTBL.mutex.synchronize{
2013              TkFont::Tk_FontUseTBL.delete(w)
2014            }
2015          end
2016        end
2017      }
2018      self
2019    end
2020 
2021    def latin_replace_core_tk8x(ltn)
2022      ltn = '{}' if ltn == ''
2023 
2024      if JAPANIZED_TK
2025        begin
2026          tk_call('font', 'delete', '@font_tmp')
2027        rescue
2028        end
2029        begin
2030          fnt_bup = tk_call('font', 'create', '@font_tmp', '-copy', @latinfont)
2031        rescue
2032          #fnt_bup = ''
2033          fnt_bup = TkFont::DEFAULT_LATIN_FONT_NAME
2034        end
2035      end
2036 
2037      begin
2038        tk_call('font', 'delete', @latinfont)
2039      rescue
2040      end
2041      create_latinfont(ltn)
2042 
2043      if JAPANIZED_TK
2044        keys = self.configinfo
2045        tk_call('font', 'delete', @compoundfont)
2046        begin
2047          tk_call('font', 'create', @compoundfont, 
2048                  '-compound', [@latinfont, @kanjifont], *hash_kv(keys))
2049  =begin
2050          latinkeys = {}
2051          begin
2052            actual_core(@latinfont).each{|key,val| latinkeys[key] = val}
2053          rescue
2054            latinkeys = {}
2055          end
2056          if latinkeys != {}
2057            tk_call('font', 'configure', @compoundfont, *hash_kv(latinkeys))
2058          end
2059  =end
2060        rescue RuntimeError => e
2061          tk_call('font', 'delete', @latinfont)
2062          if fnt_bup && fnt_bup != ''
2063            tk_call('font', 'create', @latinfont, '-copy', fnt_bup)
2064            tk_call('font', 'create', @compoundfont, 
2065                    '-compound', [@latinfont, @kanjifont], *hash_kv(keys))
2066            tk_call('font', 'delete', fnt_bup)
2067          else
2068            fail e
2069          end
2070        end
2071 
2072      else
2073        latinkeys = {}
2074        begin
2075          actual_core(@latinfont).each{|key,val| latinkeys[key] = val}
2076        rescue
2077          latinkeys = {}
2078        end
2079        begin
2080          tk_call('font', 'configure', @compoundfont, *hash_kv(latinkeys))
2081        rescue
2082          # not exist? (deleted?) -> create font
2083          tk_call('font', 'create', @compoundfont, *hash_kv(latinkeys))
2084        end
2085      end    
2086      self
2087    end
2088 
2089    def kanji_replace_core_tk8x(knj)
2090      knj = '{}' if knj == ''
2091 
2092      if JAPANIZED_TK
2093        begin
2094          tk_call('font', 'delete', '@font_tmp')
2095        rescue
2096        end
2097        begin
2098          fnt_bup = tk_call('font', 'create', '@font_tmp', '-copy', @kanjifont)
2099        rescue
2100          #fnt_bup = ''
2101          fnt_bup = TkFont::DEFAULT_KANJI_FONT_NAME
2102        end
2103      end
2104 
2105      begin
2106        tk_call('font', 'delete', @kanjifont)
2107      rescue
2108      end
2109      create_kanjifont(knj)
2110 
2111      if JAPANIZED_TK
2112        keys = self.configinfo
2113        tk_call('font', 'delete', @compoundfont)
2114        begin
2115          tk_call('font', 'create', @compoundfont, 
2116                  '-compound', [@latinfont, @kanjifont], *hash_kv(keys))
2117        rescue RuntimeError => e
2118          tk_call('font', 'delete', @kanjifont)
2119          if fnt_bup && fnt_bup != ''
2120            tk_call('font', 'create', @kanjifont, '-copy', fnt_bup)
2121            tk_call('font', 'create', @compoundfont, 
2122                    '-compound', [@latinfont, @kanjifont], *hash_kv(keys))
2123            tk_call('font', 'delete', fnt_bup)
2124          else
2125            fail e
2126          end
2127        end
2128      end    
2129      self
2130    end
2131 
2132    def measure_core_tk4x(font, win, text)
2133      0
2134    end
2135 
2136    def measure_core_tk8x(font, win, text)
2137      font = '{}' if font == ''
2138 
2139      if win
2140        number(tk_call('font', 'measure', font, 
2141                       '-displayof', win, text))
2142      else
2143        number(tk_call('font', 'measure', font, text))
2144      end
2145    end
2146 
2147    def metrics_core_tk4x(font, win, option=nil)
2148      # dummy
2149      if option
2150        ""
2151      else
2152        [['ascent',[]], ['descent',[]], ['linespace',[]], ['fixed',[]]]
2153      end
2154    end
2155 
2156    def metrics_core_tk8x(font, win, option=nil)
2157      font = '{}' if font == ''
2158 
2159      if option
2160        if win
2161          number(tk_call('font', 'metrics', font, 
2162                         "-displayof", win, "-#{option}"))
2163        else
2164          number(tk_call('font', 'metrics', font, "-#{option}"))
2165        end
2166      else
2167        l = tk_split_list(if win
2168                            tk_call('font','metrics',font,"-displayof",win)
2169                          else
2170                            tk_call('font','metrics',font)
2171                          end)
2172        r = []
2173        while key=l.shift
2174          r.push [key[1..-1], l.shift.to_i]
2175  =begin
2176          if key == '-fixed'  # boolean value
2177            r.push [key[1..-1], bool(l.shift)]
2178          else
2179            r.push [key[1..-1], l.shift.to_i]
2180          end
2181  =end
2182        end
2183        r
2184      end
2185    end
2186 
2187    ###################################
2188    # private alias
2189    ###################################
2190    case (Tk::TK_VERSION)
2191    when /^4\..*/
2192      alias actual_core             actual_core_tk4x
2193      alias configure_core          configure_core_tk4x
2194      alias configinfo_core         configinfo_core_tk4x
2195      alias current_configinfo_core current_configinfo_core_tk4x
2196      alias delete_core             delete_core_tk4x
2197      alias latin_replace_core      latin_replace_core_tk4x
2198      alias kanji_replace_core      kanji_replace_core_tk4x
2199      alias measure_core            measure_core_tk4x
2200      alias metrics_core            metrics_core_tk4x
2201 
2202    when /^8\.[0-5]/
2203      alias actual_core             actual_core_tk8x
2204      alias configure_core          configure_core_tk8x
2205      alias configinfo_core         configinfo_core_tk8x
2206      alias current_configinfo_core current_configinfo_core_tk8x
2207      alias delete_core             delete_core_tk8x
2208      alias latin_replace_core      latin_replace_core_tk8x
2209      alias kanji_replace_core      kanji_replace_core_tk8x
2210      alias measure_core            measure_core_tk8x
2211      alias metrics_core            metrics_core_tk8x
2212 
2213    else
2214      alias actual_core             actual_core_tk8x
2215      alias configure_core          configure_core_tk8x
2216      alias configinfo_core         configinfo_core_tk8x
2217      alias current_configinfo_core current_configinfo_core_tk8x
2218      alias delete_core             delete_core_tk8x
2219      alias latin_replace_core      latin_replace_core_tk8x
2220      alias kanji_replace_core      kanji_replace_core_tk8x
2221      alias measure_core            measure_core_tk8x
2222      alias metrics_core            metrics_core_tk8x
2223 
2224    end
2225  end
2226 
2227  class TkFont
2228    include TkFont::CoreMethods
2229    extend  TkFont::CoreMethods
2230  end
2231 
2232  class TkNamedFont < TkFont
2233    # for built-in named fonts
2234    def TkNamedFont.find(name)
2235      name = name.to_s
2236      unless (obj = Tk_FontNameTBL[name])
2237        obj = self.new(name) if TkFont.is_system_font?(name)
2238      end
2239      obj
2240    end
2241 
2242    def TkNamedFont.new(name, keys=nil)
2243      name = name.to_s
2244      obj = nil
2245      Tk_FontNameTBL.mutex.synchronize{
2246        unless (obj = Tk_FontNameTBL[name])
2247          (obj = self.allocate).instance_eval{
2248            @id = @compoundfont = name.to_s
2249            @latinfont = nil
2250            @kanjifont = nil
2251            @descendant = [self, self] # [latin, kanji] : dummy
2252            Tk_FontNameTBL[@id] = self
2253          }
2254        end
2255      }
2256      obj.instance_eval{ initialize(name, keys) }
2257      obj
2258    end
2259 
2260    ###########################
2261    private
2262    ###########################
2263    def initialize(name, keys=nil)
2264      @id = @compoundfont = name.to_s
2265 
2266      # if not exist named font, create it.
2267      begin
2268        if keys
2269          tk_call('font', 'configure', @compoundfont, keys)
2270        else
2271          tk_call('font', 'configure', @compoundfont)
2272        end
2273      rescue
2274        # the named font doesn't exist -> create
2275        if keys
2276          tk_call('font', 'create', @compoundfont, keys)
2277        else
2278          tk_call('font', 'create', @compoundfont)
2279        end
2280      end
2281    end
2282 
2283    def create_latinfont(fnt)
2284      # ignore
2285    end
2286    def create_kanjifont(fnt)
2287      # ignore
2288    end
2289    def create_compoundfont(ltn, knj, keys)
2290      # ignore
2291    end
2292 
2293    ###########################
2294    public
2295    ###########################
2296    def latin_font_id
2297      @compoundfont
2298    end
2299    def kanji_font_id
2300      @compoundfont
2301    end
2302  end
2303 
2304  #######################################
2305  # define system font names
2306  #######################################
2307  if Tk::TCL_MAJOR_VERSION > 8 || 
2308      (Tk::TCL_MAJOR_VERSION == 8 && Tk::TCL_MINOR_VERSION >= 5)
2309    # add standard fonts of Tcl/Tk 8.5+
2310    TkFont::SYSTEM_FONT_NAMES.add [
2311      'TkDefaultFont', 'TkTextFont', 'TkFixedFont', 'TkMenuFont', 
2312      'TkHeadingFont', 'TkCaptionFont', 'TkSmallCaptionFont', 
2313      'TkIconFont', 'TkTooltipFont'
2314    ]
2315  end
2316 
2317  # platform-specific fonts
2318  #  -- windows
2319  TkFont::SYSTEM_FONT_NAMES.add [
2320    'ansifixed', 'ansi', 'device', 'oemfixed', 'systemfixed', 'system'
2321  ]
2322 
2323  #  --  macintosh, macosx
2324  TkFont::SYSTEM_FONT_NAMES.add ['system', 'application']
2325 
2326  if Tk::TCL_MAJOR_VERSION > 8 || 
2327      (Tk::TCL_MAJOR_VERSION == 8 && Tk::TCL_MINOR_VERSION >= 5)
2328    TkFont::SYSTEM_FONT_NAMES.add ['menu']
2329  end
2330 
2331  #  --  macosx (Aqua theme)
2332  if Tk::TCL_MAJOR_VERSION > 8 || 
2333      (Tk::TCL_MAJOR_VERSION == 8 && Tk::TCL_MINOR_VERSION >= 5)
2334    TkFont::SYSTEM_FONT_NAMES.add [
2335      'systemSystemFont', 'systemEmphasizedSystemFont', 
2336      'systemSmallSystemFont', 'systemSmallEmphasizedSystemFont', 
2337      'systemApplicationFont', 'systemLabelFont', 'systemViewsFont', 
2338      'systemMenuTitleFont', 'systemMenuItemFont', 'systemMenuItemMarkFont', 
2339      'systemMenuItemCmdKeyFont', 'systemWindowTitleFont', 
2340      'systemPushButtonFont', 'systemUtilityWindowTitleFont', 
2341      'systemAlertHeaderFont', 'systemToolbarFont', 'systemMiniSystemFont', 
2342      'systemDetailSystemFont', 'systemDetailEmphasizedSystemFont'
2343    ]
2344  end