summaryrefslogtreecommitdiff
path: root/support/rfil/lib/rfil/font/glyph.rb
blob: 91b1d69422ca37ff43b25c9a76e891879948d0b3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198

module RFIL
  module Font
    class Glyph
      
      # to make Rdoc and Ruby happy: [ruby-talk:147778]
      def self.documented_as_accessor(*args) #:nodoc:
      end
      
      # Glyphname
      attr_accessor :name

      # Advance with
      attr_accessor :wx

      # Standard code slot (0-255 or -1 for unencoded)
      attr_accessor :c

      # bounding box (llx, lly, urx, ury). Array of size 4.
      # You should use the methods llx, lly, urx, ury to access the
      # bounding box.
      attr_accessor :b

      # Kern_data (Hash). The key is the glyph name, the entries are
      # _[x,y]_ arrays. For ltr and rtl typesetting only the x entry
      # should be interesting. This is raw information from the font
      # metric file. Does not change when efactor et al. are set in any
      # way. 
      attr_accessor :kern_data

      # Information about ligatures - unknown datatype yet
      attr_accessor :lig_data

      # Composite characters. Array [['glyph1',xshift,yshift],...]
      attr_accessor :pcc_data

      # Upper right x value of glyph.
      documented_as_accessor :urx
      
      # Upper right y value of glyph.
      documented_as_accessor :ury

      # Lower left x value of glyph.
      documented_as_accessor :llx

      # Lower left y value of glyph.
      documented_as_accessor :lly

      # the name of the uppercase glyph (nil if there is no uppercase glyph)
      attr_accessor :uc

      # the name of the lowercase glyph (nil if there is no lowercase glyph)
      attr_accessor :lc

      # Optional argument sets the name of the glyph.
      def initialize (glyphname=nil)
        @name=glyphname
        @lig_data={}
        @kern_data={}
        @wx=0
        @b=[0,0,0,0]
        @efactor=1.0
        @slant=0.0
      end
      
      # Lower left x position of glyph.
      def llx            # :nodoc:
        @b[0]
      end                  
      def llx=(value)    # :nodoc:
        @b[0]=value
      end 

      # Lower left y position of glyph.
      def lly            # :nodoc:
        @b[1]
      end
      def lly=(value)    # :nodoc:
        @b[1]=value
      end 
      # Upper right x position of glyph.
      def urx            # :nodoc:
        @b[2]
      end
      def urx=(value)    # :nodoc:
        @b[2]=value
      end

      # Upper right y position of glyph.
      def ury            # :nodoc:
        @b[3]
      end
      def ury=(value)    # :nodoc:
        @b[3]=value
      end
      
      # Return height of the char used for tfm file.
      def charht
        ury
      end
      
      # Return width of the char used for tfm file.
      def charwd
        wx
      end
      
      # Return depth of the char.
      def chardp
        lly >= 0 ? 0 : -lly
      end
      
      # Return italic correction of the char.
      def charic
        (urx - wx) > 0 ? (urx - wx) : 0
      end
      # Return an array with all kerning information (x-direction only)
      # of this glyph. Kerning information is an Array where first
      # element is the destchar, the second element is the kerning amount.
      def kerns_x
        ret=[]
        @kern_data.each  { |destchar,kern|
          ret.push([destchar,kern[0]])
        }
        ret
      end
      
      # Return an array with all ligature information (LIG objects) of
      # this glyph.
      def ligs
        ret=[]
        @lig_data.each  { |destchar,lig|
          ret.push(lig)
        }
        ret
      end
      
      # Return true if this char has ligature or kerning information. If
      # glyphindex is supplied, only return true if relevant. This means
      # that the second parameter of a kerning information or the second
      # parameter and the result of a ligature information must be in
      # the glyphindex. glyphindex must respond to <em>include?</em>.
      def has_ligkern?(glyphindex=nil)
        if glyphindex and not glyphindex.respond_to? :include?
          raise ArgumentError, "glyphindex does not respod to include?"
        end
        return false if (lig_data == {} and kern_data=={})
        # this one is easy, just look at lig_data and kern_data
        # more complicated, we have to take glyphindex into account
        if glyphindex
          return false unless glyphindex.include? self.name
          # right kerningpair not in glyphindex? -> false
          # right lig not in glyphindex? -> false
          # result lig not in glyphindex? -> false
          if lig_data
            lig_data.each { |otherchar,lig|
              if (glyphindex.include?(lig.right) and glyphindex.include?(lig.result))
                return true
              end
            }
          end
          if kern_data
            kern_data.each { |otherchar,krn|
              return true if glyphindex.include?(otherchar)
            }
          end
          return false
        else
          # no glyphindex
          return true
        end
        raise "never reached"
      end # has_ligkern?

      # Return true if glyph is an uppercase char, such as AE. 
      def is_uppercase?
        return @lc != nil
      end

      # Return true if glyph is a lowercase char, such as germandbls,
      # but not hyphen.
      def is_lowercase?
        return @uc != nil
      end
      
      # Return the uppercase variant of the glyph. Undefined behaviour if
      # glyph cannot be uppercased. 
      def capitalize
        @uc
      end

      # Return the lowercase variant of the glyph. Undefined behaviour if
      # glyph cannot be lowercased.
      def downcase
        @lc
      end
    end
  end
end