あのAsakusa.rbから、dm-paginationバージョン0.3.2がリリースされました。

dm-pagination-0.3.2 is out from Asakusa.rb

最近の改善が取り込まれています。
dm-paginationはMerb with DataMapper用のpaginationを提供するプラグインです。
Rails用の
pagination_scope
の姉妹プラグインです。

See Also

posted by genki genki on Tue 31 Mar 2009 at 10:32 with 0 comments

何回か忘れたので、記憶を定着させるためにメモしておきます。
rubyでLOAD_PATHに特定のディレクトリを追加したい場合、以下のように
RUBYLIB環境変数が利用できます。

sh>>
export RUBYLIB=/usr/lib/site_ruby:$RUBYLIB
<<--

posted by genki genki on Sun 29 Mar 2009 at 00:28 with 0 comments

s21gブログをRails-2.2.2からRails-2.3.2に対応させました。
主に以下のようなところで作業が発生しました。

  • session :off が不要になったので削除
  • application.rb ⇒ application_controller.rb
  • Test::Unit::TestCase から ActiveSupport::TestCaseに
    • test_helper.rbの中の定義もActiveSupport::TestCaseにする
  • formatted_xxx_url(:foo)をxxx_url(:format => :foo)に
posted by genki genki on Sat 28 Mar 2009 at 23:44 with 0 comments

Rails-2.2.2で動いているRailsアプリをRails-2.3.2に移行する場合、

pre>>
% rake rails:update
<<--

を行うと便利ですが、これを実行すると、以下のようなファイルが影響を受けます。

pre>>

Changed but not updated:

(use "git add/rm ..." to update what will be committed)

deleted: app/controllers/application.rb

modified: config/boot.rb

modified: config/environment.rb

modified: public/javascripts/controls.js

modified: public/javascripts/dragdrop.js

modified: public/javascripts/effects.js

modified: public/javascripts/prototype.js

Untracked files:

(use "git add ..." to include in what will be committed)

app/controllers/application_controller.rb

no changes added to commit (use "git add" and/or "git commit -a")
<<--

ApplicationControllerのファイル名が、application_controller.rbに変更になっています。一貫性を持たせるためでしょうね。

posted by genki genki on Sat 28 Mar 2009 at 20:43 with 0 comments

Passengerは非常に便利なのですが、
通常の設定では、アプリケーションへのアクセスが無い状態が5分程度続くと、プロセスがkillされてしまい、次回にアクセスする時に時間がかかるようになります。

これを回避するためには、httpd.confなどで、以下のように指定します。

pre>>
PassengerPoolIdleTime 0
<<--

これで、プロセス数の限界に達して追い出されるまで、Idle時間によってkillされる事は無くなります。

See Also

posted by genki genki on Sat 28 Mar 2009 at 20:32 with 0 comments

待っていたものが登場したようです。

**Rails Searchable API Doc **

ss

上記は
Rails-2.3.2のSearchable API Docです。
RailsのAPIを、class, method等を横断してLive Searchできるようです。

MerbのAPIドキュメント
と比べても、勝るとも劣らない仕上がりですね。
オフライン状態でも使えるようにダウンロードできるバージョンも用意されている模様。

posted by genki genki on Sat 28 Mar 2009 at 18:13 with 0 comments

ローカライゼーションの問題で再びRejectされたので、再度アップデート申請いたしました。

審査結果がでるまで、おそらくもう一週間ほどかかる見通しです。

お待たせして申し訳ありません。

posted by genki genki on Sat 28 Mar 2009 at 07:47 with 0 comments

Reserved Instanceを使ってみるために、ec2-api-toolsをアップデートしてみました。

pre>>
% wget http://s3.amazonaws.com/ec2-downloads/ec2-api-tools.zip
% unzip ec2-api-tools.zip
<<--

/usr/local/ec2-api-toolsあたりに移動させて、
環境変数EC2_HOMEを設定します。

Reserved Instanceを使う場合、最初に、自分が使いたいインスタンスが提供されているかどうか、以下のようにして調べます。

pre>>
% ec2drio -z us-east-1b -t m1.small
OFFERING 3a98bf7d-96c3-4d2f-a263-123fa6b46d61 us-east-1b m1.smal3y 500.0 0.03 Linux/UNIX
OFFERING 60dcfab3-a56c-4092-8c90-3677e9da02b7 us-east-1b m1.smal1y 325.0 0.03 Linux/UNIX
<<--

ゾーンとタイプを指定しています。

2カラム目にあるUUID風の文字列がoffering IDなので、これを覚えておきます。

続いて、実際にReserved Instanceを購入します。

pre>>
% ec2prio -c 1 -o 60dcfab3-a56c-4092-8c90-3677e9da02b7
<<--

-cで台数、-oで先ほどのoffering IDを指定します。
これで購入完了です。

pre>>
% ec2dri
RESERVEDINSTANCES (*****) us-east-1b m1.small Linux/UNIX 1y 0.03 325.0 1 2009-03-27T06:51:18+000payment-pending
<<--

しばらくすると(この記事を執筆時点では結構待ちました)、payment-pendingがactiveになります。

あとは、us-east-1bで、通常通りにm1.smallのインスタンスを起動すれば、
自動的にReserved Instanceの料金プランが適用されるようです。

See Also

posted by genki genki on Fri 27 Mar 2009 at 15:44 with 0 comments

Rails-2.2以前とはちょっとやり方が変わったようなので、メモしておきます。
いままでは、:session_domainを指定すれば良かったのですが、
Rails2.3では、以下のように:domainを指定するようになったようです。

ruby>>
config.action_controller.session = {
:session_key => 'session_key',
:domain => 'foo.com'
}
<<--

See Also

posted by genki genki on Wed 25 Mar 2009 at 07:34 with 0 comments

まだPokéDia-1.3のアップデート審査が通っていないのですが、
次期バージョンで実装予定のデータバックアップ・リストアについて、
実装方法を考えてみます。

データをバックアップする方法として最初に考えた方法は、
指定したメールアドレスにデータファイルを添付して送信するというものだったのですが、この場合、データをリストアするフローが以下のように面倒になってしまいます。

  1. メールの中の添付ファイルをダウンロード
  2. 添付されたデータファイルをどこかにアップロード
  3. データファイルをpokedia://restore?url={url to data file}でPokéDiaにダウンロードしてリストア

次に考えた方法は、バックアップデータファイルをアップロードするアップローダサービス(例えば backup.s21g.com)を用意して、

  1. PokéDiaからbackup.s21g.comに直接HTTP POSTでデータファイルをアップロード(メールアドレスをキーにする)すると、リストアURL(pokedia://restore?url={url to data file})を含んだメールがキーとして指定されたメールアドレスに届く。
  2. 届いたメールの中のリストアURLをタップすればリストア完了。

という流れです。今の所これが良さそうかな。
汎用的なサービスになりそうなので、http://appli.st で提供する方が良いかもしれないですね。

posted by genki genki on Sun 22 Mar 2009 at 14:36 with 0 comments

会社設立以来ほとんど更新していなかったのですが、
iPhoneアプリ等の開発で製品を紹介するページを置く場所が必要になったので、
Rails-2.3.2がリリースされた事もあり、I18nを使って国際化仕様のサイトを作りました。

http://ja.www.s21g.com/ 日本語
ss1

http://en.www.s21g.com/ 英語
ss2

従来通り、http://www.s21g.com/にアクセスすると、ブラウザの設定に従って、自動的に日本語か英語のサイトに振り分けられます。
localizationファイルをもっと用意すれば、ISOで定義されてる言語なら何語でも大丈夫なのですが、とりあえずはjaとenのみサポートです。

I18nの使い方

ローカライズファイルは、デフォルトではconfig/locales/*.ymlに配置します。
mutohさんの、
locale
locale_rails
を使うと色々と便利です。
EdgeバージョンはRails-2.3.2でも利用出来ました。

自動的にロケールを判別するために、以下のようなコードを
ApplicationControllerに書きました。

ruby>>
class ApplicationController < ActionController::Base
before_filter :set_locale

(..snip..)

def set_locale
I18n.locale = @original_locale = fallback_locale(I18n.locale)
if request.host =~ /^([\w-]+).#{HOST.split(':')[0]}/i
I18n.locale = fallback_locale($1)
end
end

private
def fallback_locale(locale)
locale = locale.to_s
@available_locales ||= Set.new(I18n.available_locales)
until locale.empty? || @available_locales.include?(locale.intern)
locale = locale.split(/([-_])/)[0..-3].join
end
locale.present? ? locale.intern : I18n.default_locale
end
<<--

実際にローカライズする手順は、以下のような感じになります。

文字列のローカライズ

*.ymlファイルで定義されているメッセージキーに対して、

yaml>>
ja:
"hello": "こんにちわ"
<<--

こんな感じにt(...)ヘルパーメソッドを使います。

ruby>>
t("hello") #=> "こんにちわ"
<<--

時刻などのローカライズ

時刻の場合もほぼ同様で、以下のような*.ymlファイルで定義されている設定に対応して、

yaml>>
ja:
date:
formats:
default: "%Y/%m/%d"
short: "%m/%d"
long: "%Y年%m月%d日(%a)"
<<--

以下のようにl(...)ヘルパーメソッドを使ってローカライズします。

ruby>>
l(Date.today, :format => :short) #=> "03/22"
<<--

テンプレートのローカライズ

Viewテンプレートを丸ごとローカライズする場合は、

  • top/index.ja.html.erb
  • top/index.en.html.erb

のようなファイル名すればOKです。

posted by genki genki on Sun 22 Mar 2009 at 09:44 with 0 comments
UL/LIタグを使ってリストを表示するときに、 コレクションが空の場合はULタグを表示したくない場合というのが頻繁にあります。 html>> <% if @posts.present? %>
    <% @posts.each do |post| %>
  • <%= h(@post.body) %>
  • <% end %>
<% end %> <<-- そういう時は、だいたいこんな感じにコードを書きます。 しかし、条件が複雑になってきたり、複数のコレクションを考えなければ行けない場合に、きれいに記述出来なくなってきます。 そんな時は、以下のようなヘルパを使って、分岐条件を遅延評価するようにすると、処理が簡潔になります。 ruby>> module ApplicationHelper def delayed_if(&block) flag = Object.new def flag.set; @value = true end def flag.reset; @value = false end result = capture(&proc{block.call(flag)}) concat(result) if flag.instance_variable_get(:@value) end <<-- 利用法 html>> <% delayed_if do |flag| %>
    <% @posts.each do |post| %>
  • <%= h(@post.body) %>
  • <% flag.set %> <% end %>
<% end %> <<-- flag.setがよばれた時だけ、delayed_ifのブロックが表示されます。 この例だと単純すぎてあまり恩恵が分かりにくいですが、 複数のコレクションを一つのULで表示する場合などでも簡潔に記述出来るようになります。
posted by genki genki on Sat 21 Mar 2009 at 17:33 with 0 comments

リソースを新規に作成する場合に、既存のものを再利用して作成したい場合は良くあると思います。
そんな時は、newアクションで:idを受け取れるようにして、
以下のようにすると、簡単に実現出来ます。

ruby>>
def new
@post = Post.new
@post.attributes = Post.find(params[:id]).attributes if params[:id]
@posts = Post.for_user(current_user).all
end
<<--

そしてposts/new.html.erbの中で

html>>
<% if @posts.present? %>

method="GET"> <%= select_tag :id, options_for_select(@posts.map{|i| [i.title, i.id]}) %> <%= submit_tag '読み込む' %>
<% end %> <<--

こんな感じに、テンプレートの読み込みフォームを作ります。
これで完了です。
Ajaxで posts/new/1 のようなURLにGETで遷移するようにした方が格好がいいかもしれません。

newアクションが:idで指定したリソースをテンプレートとして利用して新規にリソースを作成するというのは、標準的な挙動になっても良い気がします。

posted by genki genki on Sat 21 Mar 2009 at 13:18 with 0 comments

前回の申請がリジェクトされたため、再申請いたしました。
細かい点の修正だけだったので、機能的には前回お知らせした内容のままです。

またもう数日お待たせする事になってしまい、申し訳ありません。

posted by genki genki on Fri 20 Mar 2009 at 00:40 with 0 comments

久々にRailsモードが続いています。
APIを眺めていたら便利そうな機能を見つけたので紹介します。

layouts/application.html.erbの中などで、

html>>
<%= javascript_include_tag :defaults %>
<<--

のように書く事があると思いますが、この:defaults
というシンボルを指定することで、あらかじめ登録されている
expansionが展開されてincludeされます。
この:defaultsのようなものを自分で登録したい場合、

ruby>>
ActionView::Helpers::AssetTagHelper.register_javascript_expansion :foo => ["bar", "baz"]
<<--

のようにconfig/initializers/*あたりで登録しておけばOKです。
呼び出す時は

html>>
<%= javascript_include_tag :foo %>
<<--

でOK。プラグインを作るとき等に、複数のjsフィアルをまとめてincludeできるようにしておくと便利ですね。

スタイルシートの場合は、register_stylesheet_expansionという同様のメソッドを使います。

posted by genki genki on Thu 19 Mar 2009 at 10:58 with 0 comments

昨日の時点でTwitterでは話題になっていましたが、
正式にRails-2.3.2のリリースがアナウンスされたようです。

Rails 2.3: Templates, Engines, Rack, Metal, much more!

Rails 2.3 is finally done and out the door. This is one of the most substantial upgrades to Rails in a very long time.

今回のリリースの主な特徴は、

  • Templates: 自分好みのRailsアプリケーションのひな形を作る機能。
    沢山Railsアプリを作ってる人には便利そう。
  • Engines: Railsアプリをコンポーネント化して再利用する仕組み。MerbのSliceのような印象。render_componentが無くなったので、代わりにこれを使うと良いらしい。
  • Rack: Rackに対応。
  • Metal: 色々と省略して高速なレスポンスを実現する仕組み。
  • Nested forms: 頭痛への処方箋。かなり嬉しい。

全体的な印象として、Merb-1.1との差が少なくなってきた感じですね。
Rails-3(あるいはMerb-2)への道筋が見えてきた気がします。

See Also

posted by genki genki on Tue 17 Mar 2009 at 09:31 with 0 comments

便利そうなサービスを見つけたので紹介します。

RDocul.us

ss

いつでも最新のRDoc情報を配信してくれるサービスのようです。
ドキュメントはRDocがあればだいたい事足りるので、非常に助かります。

欲を言えばインクリメンタルサーチにも対応して欲しい :-)

posted by genki genki on Tue 17 Mar 2009 at 08:59 with 0 comments

Merbと違って、Railsには標準的なユーザ認証機構が用意されていないので、
昔から様々な認証用プラグインが乱立していました。
login_generator,
acts_as_authenticated,
restful_authentication,
restful_openid_authentication and so on...

今回は、@a_matsudaさんや
@lchinさんの勧めもあり、
比較的新しいClearanceという認証プラグインを試してみる事にしました。

インストール方法

config/environment.rbに

ruby>>
config.gem "thoughtbot-clearance",
:lib => 'clearance',
:source => 'http://gems.github.com',
:version => '>= 0.5.3'
<<--

config/environments/test.rbに

ruby>>
config.gem 'thoughtbot-shoulda',
:lib => 'shoulda',
:source => "http://gems.github.com",
:version => '>= 2.10.0'
config.gem 'thoughtbot-factory_girl',
:lib => 'factory_girl',
:source => "http://gems.github.com",
:version => '>= 1.2.0'
<<--

と記述し、

pre>>
% sudo rake gems:install
% sudo rake gems:install RAILS_ENV=test
<<--

あとは、

pre>>
% ./script/generate clearance
<<--

これでモデル、コントローラ、View、migrationファイルの作成が行われ、
マイグレーションの実行まで完了します。

続いて、config/environments/*.rb に、HOST="hostname"のようにホスト名を設定します。test, developmentでは"localhost"、
productionでは実際に使われるホスト名を指定すれば良いようです。
さらに、config/environment.rbの中で、

ruby>>
DO_NOT_REPLY = 'do_not_reply@s21g.com'
<<--

のように、アクティベーションメールの送信もとメールアドレスを設定します。

最後に、config/routes.rbの中で、何でも良いのでrootのNamedRouteを定義します。

ruby>>
map.root :controller => 'top'
<<--

以上で完了です。

追記

現時点でのバージョン(thoughtbot-clearance (0.5.3),
thoughtbot-factory_girl (1.2.0),
thoughtbot-shoulda (2.10.1))では、
clearanceに含まれているshoulda_macrosを手動でtest
ディレクトリの下にコピーする必要があるようです。

See Also

posted by genki genki on Mon 16 Mar 2009 at 16:13 with 0 comments
posted by genki genki on Sun 15 Mar 2009 at 23:56 with 0 comments

Skitchはスクリーンショットをとったり、図を描いたり、
画像形式を変換したりと、非常に便利な画像処理ツールで、
愛用しています。

コマンドラインからSkitchを起動出来たら便利だな、
と思って試したら、すんなり出来たので紹介します。

pre>>
% /Applications/Skitch.app/Contents/MacOS/Skitch foo.png
<<--

こんな感じでOK。convertコマンドの代わりになるかも。

posted by genki genki on Sun 15 Mar 2009 at 09:51 with 0 comments

現在アップデート申請中のPokéDia-1.3で利用可能になる
外字キーボード(Gaiji Keyboard)のデモ動画を作ってみました。

外字データ配布サイトhttp://gaiji.s21g.comから外字データをダウンロードしてきて、PokéDiaから利用しています。

無事に申請が通ると良いな。

See Also

posted by genki genki on Sun 15 Mar 2009 at 05:51 with 0 comments

PokéDiaはiPhone用の手帳アプリケーションです。
このたび、バージョン1.3のアップデート申請をいたしました。

今回のアップデートの内用は以下の通りです。

  • アドレス帳からのメールアドレスの追加
  • 外字キーボード機能
  • テーマを2つ追加
  • ウェブサイトからのメモ登録APIとアプリケーション連携機能(開発者向けの機能です)

外字キーボードはフルスクラッチで作りました。

ss1

絵文字や矢印、括弧、など、全ての記号が利用出来ます。
利用可能な外字データは、http://gaiji.s21g.com/
から配信します(3/13日現在データ準備中です)

ウェブサイトからのメモ登録APIとアプリケーション連携機能については、
ウェブサイトや他のアプリケーションから、PokéDiaにメモを登録出来る機能です。
申請が通り次第、仕様の詳細を公開いたします。

もうしばらくお待たせいたしますが、
よろしくお願いいたします。

posted by genki genki on Fri 13 Mar 2009 at 10:21 with 0 comments

Rails向けのiPhoneサイト作成用プラグインのメモです。

See Also

posted by genki genki on Wed 11 Mar 2009 at 08:18 with 0 comments

Merbのプラグインの多くは、Merb以外の場所でも使えるように設計されています。
また、いくつかのRailsプラグインも、Merbや他のプラットフォームで利用できたり、単体でも利用可能になっていたりします。

これらのプラグインは、Agnosticなプラグインと呼ばれています。
従来のプラグイン機構が、特定のフレームワークの機能を拡張する役割にとどまっていたのに対して、Agnosticなプラグインは、複数のプラットフォームを股に掛けて活躍します。

fig

このような動きは、従来のフレームワークとプラグインの関係を改めるものとして注目に値するものだと思います。
フレームワーク間で共通に必要となるようなプラグインの重要性が高まり、
今まで分散していたプラグイン開発リソースが、統合されることによって効率化がはかられたと見る事も出来ます。

これからは、フレームワークの知識だけでなく、
主要なAgnosticプラグインの利用法に習熟する事が
生産性の向上のために必要になってくるかもしれません。

posted by genki genki on Wed 11 Mar 2009 at 07:48 with 0 comments

@maihaさんを中心として、私やMerb勉強会の参加者によって作り続けていたMerbのRuby-1.9.1対応のパッチ群が、Merb本体に取り込まれました。

ss

http://github.com/wycats/merb/commits/

Merb勉強会での活動が実を結んだわけです。
めでたいです。ありがとうございます。

Merb-1.1では、Ruby-1.9.1に対応したMerbがリリースされそうです。

Merb 1.1 roadmap

posted by genki genki on Wed 11 Mar 2009 at 05:52 with 0 comments

先日送ったpatchが採用され、Ruby-1.9.1対応の
bcrypt-ruby-2.0.4がリリースされました。

http://rubyforge.org/projects/bcrypt-ruby/

Thanks you, codahale!

posted by genki genki on Tue 10 Mar 2009 at 13:10 with 0 comments

サーバ管理をしていて、root権限が必要なディレクトリに、ファイルをリポジトリからgit cloneしてきたい状況になったので、方法をメモしておきます。
まず状況の確認として、

  • gitのプロトコルにはsshを使っている
  • リポジトリサーバには、rootユーザでは鍵認証でもパスワード認証でもログインできない
  • リポジトリサーバ、clone先のサーバ双方ともfooというローカルユーザが存在。sshでリモートログインできる

という感じです。ユーザ権限でアクセス出来る場所にgit cloneする場合であれば、

pre>>
foo% git clone ssh://git.repos.com/path/to/repo.git
<<--

こんな感じで済むのですが、ファイルの作成にroot権限が必要な場合、
repoディレクトリを作成出来なくて怒られます。
かといって、rootユーザでgit cloneしようとしても、リポジトリサーバにはrootではログイン出来ないのでcloneできません。

そのような場合には、以下の手順を踏みます。

  1. clone先のサーバに ssh -A foo@target.server.com でエージェントフォワードしてログイン。
  2. ssh -A root@localhost でエージェントフォワードした状態でlocalhostにrootユーザでログイン(ターゲットサーバ上での、ローカルからのrootによるssh接続は許可する必要がある)
  3. git clone ssh://foo@git.repos.com/path/to/repo.git でclone

これでroot権限が必要な場所にfooユーザのSSHエージェントを介してリポジトリサーバに接続し、cloneできます。

注意

安全にエージェントフォワーディングを行う事が出来るのは、
接続先および踏み台にするのサーバ群の管理者たちが全て信頼できる場合に限られます。

posted by genki genki on Tue 10 Mar 2009 at 02:21 with 0 comments

Macの開発環境にEC2 ami toolsを入れる手順のメモ。
今回はmacportsのrpmを使ってインストールしました。

pre>>
% wget http://s3.amazonaws.com/ec2-downloads/ec2-ami-tools.noarch.rpm
% sudo rpm -i ec2-ami-tools.noarch.rpm --nodeps --ignoreos
<<--

これだけです。

あとは、.zshrcなどで、RUBYLIB環境変数に/usr/lib/site_rubyを加えておきます。

See Also

posted by genki genki on Mon 9 Mar 2009 at 14:34 with 0 comments

portを使っていて以下のようなエラーが出たので、対策を調べてみました。

pre>>
Unable to execute port: can't read "frameworks_dir": no such variable
<<--

Mac OS Xで(も)tamarinのabcdump.asからabcdump.exeを作る

これはports自身を更新することで、解消ができました。

ということで、以下のコマンドでportを更新。

pre>>
% sudo port -v selfupdate
% sudo port -d sync
<<--

これでエラーが出なくなりました。

posted by genki genki on Mon 9 Mar 2009 at 13:28 with 0 comments
会場にお越し下さった皆様、ありがとうございます。
posted by genki genki on Sun 8 Mar 2009 at 03:08 with 0 comments

弊社は、deployツールとしてcapistranoを使っています。
しかし、Capistranoのメンテナンスが終了するという話("Jamis Buck氏, CapistranoやSQLite/rubyの開発を終了"参照)を聞いても、
特に困らないという事に気がついて、あらためて驚きを感じました。

なぜだろうと考えてみると、それはGitとGitHubの存在による所が大きい。
GitHubにソースがある限り、メンテナが不在でも勝手にforkして
野良patchを書いたり、それを集めてきてちょっとした
stable release的なものを作ったりする事ができてしまう。

もちろんそれは、今までだって頑張れば出来た事だけれど、
Git/GitHubは、それを全く違う次元で簡単にしてしまった。

かつてはメンテナやコミッタが専権的にソフトウェア開発の決定権を握っていた構造が、Git/GitHubの登場によって、気がつかないうちに崩れ去っている。
これはソフトウェア開発史上、非常に大きな出来事なんだろう。

See Also

posted by genki genki on Thu 5 Mar 2009 at 03:32 with 0 comments

Xcodeで開発しているiPhoneアプリをgitで管理する場合には、
以下のような
.gitignore
ファイルを使っています。

pre>>
.xcodeproj/.mode1v3
.xcodeproj/.pbxuser
build
.DS_Store
<<--

posted by genki genki on Wed 4 Mar 2009 at 18:34 with 0 comments

ちょっと必要だったので作りました。

ss

CoreGraphicsを使って、指定したCGRectの中に、指定した太さの×印(Cross Sign)を描画するためのPathを生成します。

objective-c>>
void PDPathAddCrossSign(CGMutablePathRef path, CGRect rect, CGFloat thickness)
{
CGFloat diff = rect.size.width - rect.size.height;
rect = CGRectDeflateRect(rect, MAX(0, diff/2), MAX(0, -diff/2));
CGFloat radius = rect.size.width/2;
CGFloat d = sqrt(2)*thickness/2;
CGFloat cx = CGRectGetMidX(rect), cy = CGRectGetMidY(rect);
CGAffineTransform transform = CGAffineTransformMakeTranslation(cx, cy);
CGPathMoveToPoint(path, &transform, d, 0);
for(int i = 0; i < 4; ++i){
CGPathAddLineToPoint(path, &transform, radius, radius - d);
CGPathAddLineToPoint(path, &transform, radius - d, radius);
CGPathAddLineToPoint(path, &transform, 0, d);
transform = CGAffineTransformRotate(transform, M_PI/2.0f);
}
CGPathCloseSubpath(path);
}
<<--

中で呼び出してるCGRectDeflateRectは以下のようなものです。

objective-c>>
CGRect CGRectInflateRect(CGRect rect, CGFloat width, CGFloat height)
{
rect.origin.x -= width;
rect.origin.y -= height;
rect.size.width += width2;
rect.size.height += height
2;
return rect;
}

CGRect CGRectDeflateRect(CGRect rect, CGFloat width, CGFloat height)
{
return CGRectInflateRect(rect, -width, -height);
}
<<--

これを使う事で、任意の大きさ、太さ、色で×印を描画できます。

posted by genki genki on Wed 4 Mar 2009 at 00:06 with 0 comments
Contents rssrss
光ファイバーを二次元振動させて走査するAR用ディスプレイ
因果の取り違え
Swift2's defer for CoffeeScript
mongodb-3.0からcreateIndexのdropDupsが無くなったらしい
mongodb-3.0以降のWiredTigerの設定を動的に変更する方法
一般楕円の高速生成アルゴリズムへの道標
farro mantecatoのレシピ
Droonga関連の記事のまとめ
RuntimeErrorの特定のメッセージに限定してrescueする方法
jQueryでscriptタグを実行せずにappendする
Tags
memorailsお知らせrubypokediatipsmerbgitiphonemac23EC2plugin191appleblogcgclearancedemoDM
Comments rssrss
https://unosport.pl/ https://unosport.pl/: Hmm is anyone else experiencing problems with the ... 05/16 10:37
https://strategyreviewer.com/ https://strategyreviewer.com/: Marvelous, what a web site it is! This blog presen... 05/16 10:01
https://listji.com/index.php?page=user&action=pub_profile&id=72479&item_type=active&per_page=16 https://listji.com/index.php?page=user&action=pub_profile&id=72479&item_type=active&per_page=16: As tһe premier furniture store аnd comprehensive f... 05/16 07:16
https://khvanchkaravino.ru https://khvanchkaravino.ru: Квартира мечты за 2 месяца — помогаем выбрать мебе... 05/16 05:06
https://www.tequilagames.com https://www.tequilagames.com: Thanks for finally writing about >something new an... 05/16 03:16
https://%EB%B6%80%EB%B9%84%EC%A3%BC%EC%86%8C.isweb.co.kr/ https://%EB%B6%80%EB%B9%84%EC%A3%BC%EC%86%8C.isweb.co.kr/: We absolutely love your blog and find a lot of you... 05/16 01:40
https://zgarcitul01.com https://zgarcitul01.com: Hi my loved one! I wish to say that this post is a... 05/16 01:10
https://pelnadobrego.pl https://pelnadobrego.pl: I love what you guys tend to be up too. This sort ... 05/15 22:11