昨日の日記からの続き。今日は、Pebble Time / Pebble Time Steel 用のプラットフォーム(Basalt)で拡張されたグラフィック描画処理を触っていく。テキストは昨日に引き続き「Drawing Graphics」で、今日は「Advanced Features」の章から始める。
Basalt ではアンチエイリアスが使えるようになって、よりスムーズなラインが引けるようになり、また隣接するカラーもエッジが目立たなくなるようだ。SDK 3.0 からはデフォルトでアンチエイリアスが効くようになっていて、graphics_context_set_antialiased()
でそのコントロールができるとのこと。引数が true
でアンチエイリアスが ON、false
で OFF という制御になっている。
アンチエイリアスが効くのは次の関数とのこと。
一方で、アンチエイリアスが効かない関数もあるそうだ。
ふむ、graphics_draw_text()
はアンチエイリアスが効かないのか。テキストもアンチエイリアスが効くようになるといいな。
ではアンチエイリアスの ON / OFF による描画の違いを体験してみよう。昨日までのソースコードから、昨日追加した分をいったん削除して、そこにアンチエイリアスのサンプルとして載っているコードを追加してみる。
static void layer_update_proc(Layer *layer, GContext *ctx) {
// Draw an antialiased circle with smoothed edges
graphics_draw_circle(ctx, GPoint(35, 35), 30);
// Disable antialiasing
graphics_context_set_antialiased(ctx, false);
// Draw a regular circle
graphics_draw_circle(ctx, GPoint(110, 35), 30);
}
このコードが意味するところは、画面内に 2 つの円を描くこと。
その他に必要な処理を付け加えて、build & install したものがこれ。
表示を削除した分と追加した分がひとつの diff になっているけど、本当ならこれは commit を分けるべきだよな。Removed & Add という 2 つの目的が入っている良くない commit の例がこれだ。良い子は真似しちゃダメなタイプだよ、これ、きっと。
graphics_context_set_stroke_width()
関数で、描画するラインの幅をセットできる。ひとつ注意点が書かれていて、いまのところラインの幅( stroke width )には奇数の値しかセットできないとのこと。
なんでそんな制限が?って思ったけど、恐らく中心線に 1 ドットあり、その左右(もしくは上下)に 1 ドットを引いた分の半分のサイズで描画しているんじゃないかな。例えば、graphics_context_set_stroke_width()
で 3 を指定した場合は、(3 - 1) / 2 = 1 ドットを左右に描画している。5 を指定した場合は、(5 - 1) / 2 = 2 ドットを中心線の左右に描画している感じ。引数に偶数を指定した場合、例えば 2 とかだと、(2 - 1) / 2 = 0.5 ドットとなってしまい、いまの Pebble では 0.5 ドット単位の描画はできないという状態なのではなかろうか。本当かどうかは知らないけど(笑)
さて空想はここまでにして、サンプルを記述して実行してみる。
またしても Remove & Add している commit なのでアレである。
次にビットマップ画像のローテーション方法を学ぶ。「ビットマップのローテーションは CPU パワーを食うので、バッテリの減りが速いぞ!」という注意書きがある。「できることなら Draw Commands とか GPaths を使った方がいいよ」的なアドバイスも書かれている。
とは言え、その方法は知っておいても良いだろうと思うので、試してみよう。画像は、前回使ったアイコンを再利用する。appinfo.json
の設定はそのとき使った内容のままだ。
メインのコードはこのように説明されている。
static void update_proc(Layer *layer, GContext *ctx) {
// Get image center
GRect img_bounds = gbitmap_get_bounds(s_bitmap);
GPoint src_ic = grect_center_point(&img_bounds);
// Get context center
GRect ctx_bounds = layer_get_bounds(layer);
GPoint ctx_ic = grect_center_point(&ctx_bounds);
// Angle of rotation
int angle = (45 * TRIG_MAX_ANGLE) / 360;
// Draw!
graphics_draw_rotated_bitmap(ctx, s_bitmap, src_ic, angle, ctx_ic);
}
画像の回転を実行しているのは graphics_draw_rotated_bitmap()
の部分。引数に「中心」を意味するものが 2 つあって、どういう意味なんだろ?と思っていたんだけど、画像の中心と、その画像の中心をレイヤーのどこに合わせるか?という指定みたいだ。
その他の実装も加えて実行してみたらこんな感じ。
最後に「Pebble」の「P」を描くサンプルが掲載されているので実行してみる。これは、ここまでで学んだことをひとまとめにしたヤツなので、個別に解説するところは無さそう。実行してみるとこんな感じになった。
これで「Drawing Graphics」のページはひととおり終わり。次は「Animating Layers」あたりを学んでみようかな。