Xamarin.MacでCALayerにベジェ曲線を描画する

Xamarin.MacでCALayerにベジェ曲線を描画する方法です。

サンプルプロジェクトはこちら。

NSViewを継承したクラスを作成します。ICALayerDelegateも継承します。

public partial class SampleView : AppKit.NSView, ICALayerDelegate
{
}

CALayerのインスタンス変数を用意して、

private CALayer bgLayer;

コンストラクタが呼ばれたときに、Layer Backed Viewにします。

bgLayer = new CALayer();
this.Layer = bgLayer;
this.WantsLayer = true;
this.LayerContentsRedrawPolicy = NSViewLayerContentsRedrawPolicy.OnSetNeedsDisplay;
this.Layer.Delegate = this;

必要に応じて、Layout()でレイアウトの設定をします。

public override void Layout()
{
    base.Layout();
    this.Layer.Frame = this.Frame;
}

DrawLayer()で描画処理を行います。

[Export("drawLayer:inContext:")]
public void DrawLayer(CALayer layer, CoreGraphics.CGContext context)
{
    NSGraphicsContext.GlobalSaveGraphicsState();
    NSGraphicsContext graphicsContext = NSGraphicsContext.FromGraphicsPort(context, true);
    NSGraphicsContext.CurrentContext = graphicsContext;

    NSBezierPath path = new NSBezierPath();
    //ベジェ曲線
    var x1 = this.Frame.Left;
    var y1 = this.Frame.Top;
    var x2 = this.Frame.Right;
    var y2 = this.Frame.Bottom;
    path.MoveTo(new CoreGraphics.CGPoint(x1, y1));
    path.CurveTo(new CoreGraphics.CGPoint(x2, y1),
                 new CoreGraphics.CGPoint(x1, y2),
                 new CoreGraphics.CGPoint(x2, y2));
    //背景は白
    NSColor.White.Set();
    path.Fill();
    //線は青
    NSColor.Blue.Set();
    //線の太さ
    path.LineWidth = 2;
    path.Stroke();

    NSGraphicsContext.GlobalRestoreGraphicsState();
}

nodistでnpmを最新版にバージョンアップするには

nodistでnpmを最新版にバージョンアップするには

最新版のNode.jsをインストール

nodist latest

現在のnodeのバージョンにあったnpmを使用する

nodist npm match

追記

「nodist npm match」を実行すると、以下のエラーメッセージが表示されるようになった。

>nodist npm match
npm match
stream.js:74
    throw er; // Unhandled stream error in pipe.
    ^

Error: Failed to read response from https://codeload.github.com/npm/npm/tar.gz/v6.4.1
    at Request.<anonymous> (C:\Program Files (x86)\Nodist\lib\build.js:110:25)
    at emitOne (events.js:96:13)
    at Request.emit (events.js:188:7)
    at Request.onRequestResponse (C:\Program Files (x86)\Nodist\node_modules\request\request.js:954:10)
    at emitOne (events.js:96:13)
    at ClientRequest.emit (events.js:188:7)
    at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:473:21)
    at HTTPParser.parserOnHeadersComplete (_http_common.js:99:23)
    at TLSSocket.socketOnData (_http_client.js:362:20)
    at emitOne (events.js:96:13)
    at TLSSocket.emit (events.js:188:7)
    at readableAddChunk (_stream_readable.js:176:18)
    at TLSSocket.Readable.push (_stream_readable.js:134:10)
    at TLSWrap.onread (net.js:551:20)

エラーの原因はダウンロード先のURLが変更になったためらしい。

nodistが対応するまでの間、ソースコードを修正して対策する。

“C:\Program Files (x86)\Nodist\lib\npm.js”をエディタで開き、
127行目のURLを修正する。

NPMIST.downloadUrl = function(version){
  // return 'https://codeload.github.com/npm/npm/tar.gz/vVERSION'
  return 'https://codeload.github.com/npm/cli/tar.gz/vVERSION'
    .replace('VERSION',version.replace('v',''));
};

次に、ダウンロードに失敗したときに作成されたフォルダー(“C:\Program Files (x86)\Nodist\npmv\6.4.1”)を削除する。

これで、もう一度「nodist npm match」を実行するとインストールできる。

Google Homeに話をさせる

castv2-clientのインストール

castv2-clientをインストールします。

npm install castv2-client

Windowsの場合は、

npm install castv2-client --no-optional

google-tts-apiのインストール

google-tts-apiをインストールします。

npm install google-tts-api --save

Google Homeに話をさせるプログラム

Google Homeに話をさせるプログラムです。

環境に合わせて、変数ipの値を変更してください。

// Google-HomeのIPアドレス
const ip = '192.168.97.2';

次の変数を変更することで、話す言葉を変更できます。
Google TTS APIの制限により、変数textは最大200文字までです。

// 読み上げる文字列
const text = 'こんにちは';
// 言語
const lang = 'ja-JP';
// 読み上げ速度
const speed = 1;

以下、プログラムです。

const googleTTS = require('google-tts-api');
const Client = require('castv2-client').Client;
const DefaultMediaReceiver = require('castv2-client').DefaultMediaReceiver;

// 読み上げる文字列
const text = 'こんにちは';
// 言語
const lang = 'ja-JP';
// 読み上げ速度
const speed = 1;
// Google-HomeのIPアドレス
const ip = '192.168.97.2';

const get_TTS_URL = (text, lang, speed) => {
    return googleTTS(text, lang, speed).then(function (url) {
        return url;
    }).catch(function (err) {
        console.error(err.stack);
        return '';
    });
};

const say = (host, content) => {
    const client = new Client();
    client.connect(host, function () {
        client.launch(DefaultMediaReceiver, function (err, player) {
            if (err) {
                console.log(err);
                return;
            }

            player.on('status', function (status) {
                console.log(`status broadcast playerState=${status.playerState}`);
            });

            const media = {
                contentId: content,
                contentType: 'audio/mp3',
                streamType: 'BUFFERED'
            };
            player.load(media, { autoplay: true }, function (err, status) {
                client.close();
            });
        });
    });
    client.on('error', function (err) {
        console.log(`Error: ${err.message}`);
        client.close();
    });
};

async function main() {
    const url = await get_TTS_URL(text, lang, speed);
    if (url == '') return;
    say(ip, url);
}

main();

Ubuntuにnode.jsの最新版をインストールするには

node.jsのサイトにインストール方法が書かれています。

Node.js v9 を利用するには

curl -sL https://deb.nodesource.com/setup_9.x | sudo -E bash -
sudo apt-get install -y nodejs

Node.js v8 を利用するには

curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
sudo apt-get install -y nodejs