cairoの文字の位置関係の見直し

cairoの文字の位置関係を見直しました。
文字のセンターは
ext = c.text_extents(text)
c.move_to((ext.x_bearing + ext.width) / -2, ext.height / 2)
で、よさそうです。
他の点も調べときました。
move_toは、絶対座標[0, 0]に部品の基準点を合わせてます。
c.matrix = Cairo::Matrix.translate(x, y)
で、任意の場所に置く。
この方法で位置関係をコントロールしてます。
マフィン変換を使いたい時は行列の乗算を使ってます。

#!usr/bin/env ruby

require 'sdl'
require 'cairo'

class BackGround
def initialize(w, h)
@w, @h = w, h
end

def update(c)
c.set_source_color(:snow)
c.rectangle(0, 0, @w, @h)
c.fill
c.set_source_color(:teal)
c.move_to(0, @h / 2)
c.line_to(@w, @h /2)
c.move_to(@w / 2, 0)
c.line_to(@w / 2, @h)
c.stroke
end
end

class Item
def initialize(w, h)
@x, @y = w / 2, h / 2
@text = 'CAIRO'
end

def update(c)
c.matrix = Cairo::Matrix.translate(@x, @y)
c.font_size = 50
ext = c.text_extents(@text)
c.set_source_color(:blue)
c.circle(0, 0, ext.x_bearing)
c.stroke
#c.circle(0, 0, -ext.y_bearing)
#c.stroke
c.set_source_color(:teal)
c.circle(0, 0, ext.width)
c.stroke
c.circle(0, 0, ext.height)
c.stroke
c.set_source_color(:green)
c.circle(0, 0, ext.x_advance)
c.stroke
#c.circle(0, 0, -ext.y_advance)
#c.stroke
#no touch
c.set_source_color(:black)
c.move_to(0, 0)
c.show_text(@text)
c.set_source_color(:blue)
#right_top
c.move_to(-ext.x_bearing, ext.height)
c.show_text(@text)
#left_top
c.move_to(-ext.x_bearing - ext.width, ext.height)
c.show_text(@text)
#right_bottom
color = Cairo::Color.parse(:green)
color.alpha = 0.6
c.set_source_color(color)
c.move_to(-ext.x_bearing, 0)
c.show_text(@text)
#left_bottom
c.move_to(-ext.x_bearing - ext.width, 0)
c.show_text(@text)
#center
color = Cairo::Color.parse(:red)
color.alpha = 0.7
c.set_source_color(color)
c.move_to((ext.x_bearing + ext.width) / -2, ext.height / 2)
c.show_text(@text)
end
end

class Phase
def initialize(w, h)
@w, @h = w, h
@screen = SDL::Screen.open(@w, @h, 32, 0)
@image = Cairo::ImageSurface.new(@w, @h)
@items = []
@items << BackGround.new(@w, @h)
@items << Item.new(@w, @h)
end

def update(c)
@items.each {|obj| obj.update(c)}
end

def run
loop do
while e=SDL::Event.poll
exit if e.kind_of?(SDL::Event::Quit) || (e.kind_of?(SDL::Event::KeyDown) && e.sym == SDL::Key::ESCAPE)
end
c = Cairo::Context.new(@image)
self.update(c)
surface = SDL::Surface.new_from(@image.data, @w, @h, 32, @image.data.size / @h, 0, 0, 0, 0)
@screen.put(surface, 0, 0)
@screen.flip
SDL.delay(20)
end
end
end

w, h = 350, 350
SDL.init(SDL::INIT_VIDEO)
Phase.new(w, h).run
[PR]
by gaziya | 2011-05-29 12:30