Class: C64GeosFont

Inherits:
C64GeosFile show all
Defined in:
lib/native_file_types/c64/C64GeosFont.rb

Constant Summary collapse

TEXT_COLOUR =
C64::COLOR_DKGRAY
BACKGROUND_COLOUR =
C64::COLOR_LTGRAY

Instance Attribute Summary

Attributes inherited from NativeFileType

#aux_code, #contents, #file_system_image, #file_type, #filename

Instance Method Summary collapse

Methods inherited from C64GeosFile

#contents, #header_filename, #icon_background, #icon_bitmap, #icon_foreground, #icon_format, #icon_height, #icon_tag, #icon_width, #info_block, #load_address, #parent_application, #record_nos, #to_hex_dump, #to_icon, #type_description

Methods inherited from CbmFile

file_system_file_types, #type_description

Methods inherited from NativeFileType

#<=>, #==, all_native_file_types, best_fit, code_for_tests, compatability_score, #data_without_header, file_type_matches?, #full_filename, #header_length, #initialize, is_valid_file_if, #load_address, load_address, matching_score, native_file_types_possible_on_file_system, non_matching_score, #to_hex_dump, #to_info_dump, #type_description

Methods included from SubclassTracking

extended

Constructor Details

This class inherits a constructor from NativeFileType

Instance Method Details

#bitstreams(point_size, char) ⇒ Object



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
# File 'lib/native_file_types/c64/C64GeosFont.rb', line 150

def bitstreams(point_size,char)
	font_data=@contents[point_size+1]
	return nil if font_data.nil?
	bit_stream_index=font_data[0x04]+0x100*font_data[0x05]
	bit_stream_base=font_data[0x06]+0x100*font_data[0x07]
	char_pointer=2*((char[0]%0x80)-0x20)
	start_of_char=font_data[char_pointer+bit_stream_index]+0x100*font_data[char_pointer+bit_stream_index+1]
	start_of_next_char=font_data[char_pointer+bit_stream_index+2]+0x100*font_data[char_pointer+bit_stream_index+3]
#	puts "# #{filename} #{point_size} #{char} #{start_of_char} - #{start_of_next_char}"
	bitstream=[]
	char_height(point_size).times do |line|
		bitstream[line]=[]
		bit_counter=0
		start_of_line_bitstream=line*bytes_in_bitstream(point_size)+bit_stream_base
		(start_of_char..start_of_next_char-1).each do |bit_offset|
			byte_offset=bit_offset/8
			bitmask=0b10000000>>(bit_offset % 8)
			byte=font_data[start_of_line_bitstream+byte_offset]
#			puts "%08b:%08b==%08b" % [byte,bitmask,byte & bitmask]
			bitstream[line][bit_counter]=(((byte & bitmask)!=0)? 1 : 0)
			bit_counter+=1
		end	
#		bitstream[line][bit_counter]="\n"
	end
	bitstream
end

#bytes_in_bitstream(point_size) ⇒ Object



133
134
135
136
137
# File 'lib/native_file_types/c64/C64GeosFont.rb', line 133

def bytes_in_bitstream(point_size)
	font_data=@contents[point_size+1]
	return nil if font_data.nil?
	font_data[0x01]+font_data[0x02]*100	
end

#char_height(point_size) ⇒ Object



139
140
141
142
143
# File 'lib/native_file_types/c64/C64GeosFont.rb', line 139

def char_height(point_size)
	font_data=@contents[point_size+1]
	return nil if font_data.nil?
	font_data[0x03]
end

#char_width(point_size, char) ⇒ Object



121
122
123
124
125
126
127
128
129
130
131
# File 'lib/native_file_types/c64/C64GeosFont.rb', line 121

def char_width(point_size,char)
	font_data=@contents[point_size+1]
	return nil if font_data.nil?
	bit_stream_index=font_data[0x04]+0x100*font_data[0x05]
	char_pointer=2*((char[0]%0x80)-0x20)
	start_of_char=font_data[char_pointer+bit_stream_index]+0x100*font_data[char_pointer+bit_stream_index+1]
	start_of_next_char=font_data[char_pointer+bit_stream_index+2]+0x100*font_data[char_pointer+bit_stream_index+3]
	width=(start_of_next_char-start_of_char)
	raise "invalid char width #{width} for char $#{"%02x" % char[0]} point size #{point_size} - char pointer=#{char_pointer}" if width>(2*point_size)
	width
end

#draw_char(canvas, point_size, char, x, y, colour) ⇒ Object



188
189
190
191
192
193
194
195
# File 'lib/native_file_types/c64/C64GeosFont.rb', line 188

def draw_char(canvas,point_size,char,x,y,colour)
	lines=bitstreams(point_size,char)
	lines.length.times do |line|
		lines[line].length.times do |pixel|
			canvas[x+pixel,y+line]=colour if lines[line][pixel]==1
		end
	end
end

#draw_string(canvas, point_size, string, start_x, start_y, colour) ⇒ Object



197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/native_file_types/c64/C64GeosFont.rb', line 197

def draw_string(canvas,point_size,string,start_x,start_y,colour)
	x=start_x
	y=start_y
	string.each_byte do |b|
		c=b.chr
 	width=char_width(point_size,c)
 	if (x+width>=picture_width) then
 		x=0
 		y+=point_size
 	end
 	break if (y+point_size)>=picture_height
		draw_char(canvas,point_size,c,x,y,colour)
		x+=width
	end
	[x,y]
end

#font_formatObject



30
31
32
# File 'lib/native_file_types/c64/C64GeosFont.rb', line 30

def font_format
	:bdf
end

#lengthsObject



109
110
111
112
113
114
115
116
117
118
119
# File 'lib/native_file_types/c64/C64GeosFont.rb', line 109

def lengths
	if @lengths.nil? then
		@lengths=[]
		16.times do |i|
			length=info_block[2*i+0x61]+100*info_block[2*i+0x62]
			break if length==0
			@lengths<<length
		end
	end
	@lengths
end

#line_of_print(point_size) ⇒ Object



145
146
147
148
149
# File 'lib/native_file_types/c64/C64GeosFont.rb', line 145

def line_of_print(point_size)
	font_data=@contents[point_size+1]
	return nil if font_data.nil?
	font_data[0x00]
end

#meta_dataObject



214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# File 'lib/native_file_types/c64/C64GeosFont.rb', line 214

def 
	return super unless @contents.kind_of?(Array) && !info_block.nil?
	@meta_data["geos_font_id"]="$%02x" % (info_block[0x80]+info_block[0x81]*100)
	@meta_data["geos_font_point_ids"]=(point_ids.collect{|x| '$%04x' % x}).join(",")
	@meta_data["geos_font_point_sizes"]=point_sizes.join(",")
	@meta_data["geos_font_lengths"]=(lengths.collect{|x| '$%04x' % x}).join(",")
#	point_sizes.each do |point_size|
#		prefix="geos_font_point_size_#{point_size}"
#		font_data=@contents[point_size+1]
#		next if font_data.nil?
#		@meta_data["#{prefix}_line_of_print"]=font_data[0x00]
#		@meta_data["#{prefix}_bytes_in_bitstream"]=bytes_in_bitstream(point_size)
#		@meta_data["#{prefix}_character_height"]=char_height(point_size)
#		@meta_data["#{prefix}_character_width_space"]=char_width(point_size," ")
#		@meta_data["#{prefix}_character_width_A"]=char_width(point_size,"A")
#		@meta_data["#{prefix}_bitstream_A"]=bitstreams(point_size,"A")		
#  	end
	
	super
end

#normalised_font_name(point_size = point_sizes.last) ⇒ Object



34
35
36
37
# File 'lib/native_file_types/c64/C64GeosFont.rb', line 34

def  normalised_font_name(point_size=point_sizes.last)
	"peekbot-#{filename.downcase.gsub(/\W/,"-")}#{ filename=~/\d$/ ? "" : "-"+point_size.to_s}"

end

#picture_formatObject



26
27
28
# File 'lib/native_file_types/c64/C64GeosFont.rb', line 26

def picture_format
  :png
end

#picture_heightObject



22
23
24
# File 'lib/native_file_types/c64/C64GeosFont.rb', line 22

def picture_height
	240
end

#picture_widthObject



19
20
21
# File 'lib/native_file_types/c64/C64GeosFont.rb', line 19

def picture_width
	320
end

#point_idsObject



90
91
92
93
94
95
96
97
98
99
100
# File 'lib/native_file_types/c64/C64GeosFont.rb', line 90

def point_ids
	if @point_ids.nil? then
		@point_ids=[]
		16.times do |i|
			point_id=info_block[2*i+0x82]+100*info_block[2*i+0x83]
			break if point_id==0
			@point_ids<<point_id 
		end
	end
	@point_ids
end

#point_sizesObject



101
102
103
104
105
106
107
108
# File 'lib/native_file_types/c64/C64GeosFont.rb', line 101

def point_sizes
	r=[]
	@contents.length.times do |record_no|
			next if record_no==0
			r<<record_no-1 unless @contents[record_no].nil? 
	end
	r
end

#to_font(point_size = point_sizes.last) ⇒ Object

export font in Glyph Bitmap Distribution Format (BDF)



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
# File 'lib/native_file_types/c64/C64GeosFont.rb', line 40

def to_font(point_size=point_sizes.last)
	
	s="
STARTFONT 2.1
FONT #{normalised_font_name(point_size)}	
SIZE #{point_size} 75 75
COMMENT image: #{file_system_image.filename}
COMMENT filename: #{filename}
COMMENT timestamp: #{Time.now}
FONTBOUNDINGBOX #{char_height(point_size)} #{char_height(point_size)} 0 0
STARTPROPERTIES 2
FONT_ASCENT #{line_of_print(point_size)}
FONT_DESCENT #{char_height(point_size)-line_of_print(point_size)}
ENDPROPERTIES


CHARS 95"	
	(32..126).each do |b|

		dwidth=char_width(point_size,b.chr) #width in pixels
		swidth=(1000*dwidth)/point_size #width in 'Scalable Width' units

		s<<"
STARTCHAR U+#{"%04x" % b}
ENCODING #{b}
SWIDTH	#{swidth} 0
DWIDTH #{dwidth} 0
BBX #{dwidth} #{point_size} 0 #{line_of_print(point_size)-point_size}
BITMAP
"
		lines=bitstreams(point_size,b.chr)		
		lines.length.times do |line|
			bitmap=0
			dwidth.times do |pixel|
				bitmap=bitmap<<1
				bitmap+=1 if (lines[line][pixel]==1)
			end
			bitmap_byte_width=((dwidth+7)/8)
			bitmap<<=((8-(dwidth%8))%8)
			s<<("%0#{2*bitmap_byte_width}x\n" % bitmap)
		end
		s<<"ENDCHAR\n"	
	end	

s<<"
ENDFONT
"
	s
end

#to_pictureObject



179
180
181
182
183
184
185
186
# File 'lib/native_file_types/c64/C64GeosFont.rb', line 179

def to_picture
  require 'PatchedPNG'
  canvas = PNG::Canvas.new picture_width,picture_height, BACKGROUND_COLOUR
  draw_sampler(canvas)
  png = PNG.new canvas
  result=png.raw_bytes
  result
end