2015年7月12日 (日)

新骨言道、あるいは、WPFが言語を意識してフォントを切り替えているらしい件

 WPFには Language という dependency property (日本語では「依存関係プロパティ」と言うらしい) がある。このあたりに説明があるが、これを読んでも、どういう働きをするのかさっぱりわからない。

それで、ふと思いついてサンプルプログラムを書いてみたところ、どうやら font fallback (日本語では「フォンント フォールバック」と言うらしい) の選択に使っているらしい。いや、他にも使っているのかもしれないが。

と、いうことで、これがサンプル。(例によって、画像をクリックすると拡大します。)

Wpf1

バリバリのWPFプログラマーの皆さんには常識だったりするのかもしれないが、そういう層と、こういう地域による漢字の字体差に関心がある層との間にはかなり距離があるような気がする。後者の人たちは、マイクロソフトがどういう努力をしているか全然知らないんじゃないかという気もする。このサンプルを見て面白がっていただければ幸いです。

さて、プログラマ的には、見所は、

  • XAML の Label 要素には、それぞれ異なる Language 属性を指定しているが、フォントに類するものは指定していない。
  • フォントの指定は Window 要素に対して行っており、そこに FontFamily="Arial" と書いてある。

というあたり。

後者がどうして見所なのかというと、次のスクリーンショットを見るとわかる。

Wpf2

こちらは、Language の値によらず同じ表示になっているが、XAML 上の違いは、WindowFontFamily を削除しただけ。なぜ、そうなるのか、よくわかっていないのだが、どうやら Label/@Languageの働きは、最初からフォントを選ぶわけではなくて、フォント フォールバックに影響を与えるだけらしい、という気がする。

Visual Studio で WPF アプリの XAML 書いている人は先刻ご承知と思うが、Visual Studio のウィザードが生成する雛形 XAML には、FontFamily 属性はついていない。FontFamily 属性を指定していない XAML の要素のプロパティを Visual Studio で見ると、FontFamily のデフォルトは Meirio UI である、と表示される。(日本語 Windows で開発している場合。) この、「デフォルトは Meiryo UI」ということの意味も、よくわからないのだが、これは「実行時には Meiryo UI が使われる」ということではなくて、「FontFamily として Meiryo UI が指定されているものとみなす」ということのようだ。そうでないと、ここで観察した動作は説明できないように思う。

つまり、FontFamily="Arial" があると、各 Label では Arial を使って「新骨言道」と表示しようとするが、Arial というフォントにはそんな文字は含まれていない。それでフォント フォールバックの仕組みが働き、Language の値を参照してフォントを選択する。他方、FontFamilyがないと、まず FontFamily のデフォルト値として Meiryo UI が採用され、各 Label は Meiryo UI を使って「新骨言道」と表示しようとする。Meiryo UI にはこの4文字が含まれるのでフォント フォールバックの仕組みは働かず、Langauge が参照されることもない。そういうことなのだろうと思う。

いわゆる英語版のウィンドウズでは、フォントのデフォルトは Meiryo UI ではない。Segoe UI になるはずだ。Segoe UI にも、「新骨言道」は含まれない。ということは、上の 2 個目のサンプル プログラムは、完全に同一の XAML であっても、英語版の Windows で開発すると、1 個目のサンプルと同じ表示になるのだろうか。それとも、開発した環境じゃなくて、実行した環境によって、つまり 2 個目のサンプル プログラムは、英語版の Windows で実行すると、1 個目のサンプルと同じ表示になるのだろうか。いずれにしても気持ち悪いし、前者ならまだしも、後者だとすると、これはサポート担当者には悪夢じゃなかろうか。(この悪夢を避けるためには、Language 属性の使用を禁止するだけでいいのだろうが。

ちなみに、WPF ではデフォルトのフォントはどうやって決まるのか、という点は、世界中のプログラマを悩ませている謎のようだ。英語でそれっぽい検索をすると、様々な驚くべき現象に出会った人たちがみつかる。MSDN のサポート フォーラムにも似たような質問が多数ある。マイクロソフト側の人の回答は大抵の場合「様々な要因によって最適なものが選択されます」みたいな、意味がわからないものだ。たぶん、回答している人にもよくわかってないんじゃないかと思う。

2015年5月 3日 (日)

プライバシーポリシー

Google Playではコンテントレーティングを義務付けるので、今のうちにレーティングを付けておかないとアプリが削除されるよ。

Googleからそんな感じのメールが来た。いや、来たのは1月くらい前だけど、レーティングとかいかにも大変そうだったので、放置していたのだ。そうしたら、5月5日までにレーティングしないと削除するよ、っていうメールが来た。幸い連休でヒマなので、なんとかしようと始めたのだが。

レーティング以前に、Google Playではいろいろと必須情報が増えていて、まずそれを追加しないとレーティングに進めないという罠。大きなサイズの画像とか、そういうのはなんとかでっち上げるが、いきなり「プライバシーポリシーのURLが必須です」と言われても。

しかたないので、とりあえず一筆書き、ここに「掲載」したうえで、そのURLを設定。意味あるんですかね、こういうの。

そこを突破すれば、本題のレーティングは拍子抜けするほど簡単で、すぐにできました。質問10個ちょいにYes/Noで答えるだけ。結果は「3歳以上」。(13じゃなくて3歳。)3歳未満が除外されているのはなぜなのだろう。ま、いいけど。

ちなみに、設定したのは「これ」と「これ」です。たった今は従来の表示のままですが、半日くらいで更新されるはず。

※ まだGoogle Playのページは更新されていませんが、先にIARBからメールが来て、こういうのをもらいました。

2014年12月16日 (火)

WiMAX 2+ の IPv6 挙動不審

昨夜、Raspberry Pi の公式ウェブサイトにアクセスしたらレスポンスが非常に悪く、イギリスは遠いので途中で何か起きてるかな、なんて思ってました。

さきほど、複数のウェブサイトで、レスポンスが非常に悪く、でもいちどトップページが表示されるとしばらくの間は問題なく、でも時間が経つとまたレスポンスが悪くなるという現象に遭遇し、どうもローカルな問題なんじゃないか、WiMAX の調子が悪いんじゃないか、と疑ったわけです。

いくつか試した中で、ふと思いついて www.kame.net にアクセスしたら、とても悪いレスポンスの後で表示された亀は停止していて、左下を見ても IPv4 だって言われちゃいました。そう、IPv6 デビューなんて言っていたら、いつの間にか v6 の接続性が失われていたのです。ブラウザは、まずv6でアクセスし、それがタイムアウトしたら v4 に切り替えるという動作だったようで、レスポンスが悪いのは v6 のタイムアウト分、しばらくの間問題ないのは unreachability caching だったようです。

おいおい、フレッツじゃないんだから、みたいな気分です。(最近は、フレッツ対策の入った日本独自仕様ルーターが増えているようなので、問題が起きにくくなっているみたいではありますが。)

とりあえずルーター(NAD11)を再起動したら、復旧しました。IPv6もアクセスできています。

とは言え、また接続できなくなってしまうかもしれないというのは不安です。今度同様の現象が起きたら、もう少し詳しく調べてみようと思っています。

# なーんか、アレですかね、いわゆる保証外の使い方、なんでしょうか、IPv6 を有効にするっていうのは。こういう問題があることがわかっているので、UQ は v6 使えるとは一言も言ってない、なんてオチだったら悲しいな…。

2014年12月13日 (土)

WiMAX 2+ デビューのつもりが リアル IPv6 デビューに なっちゃった件

いや、怒ってません。むしろ嬉しい。

でも、全くの想定外で、事前に情報が何も得られなかったことについては、ちょっと不満があるのも事実。

このブログには、ほとんど書いていないけれど、実は私は WiMAX のファンである。2009年初頭、ついに日本で WiMAX サービスが開始されることになり、通信料無料のいわば「オープンβ」サービスが始まるとともに、端末の無料モニターが募集された。さっそく応募したが落選。それが確定した翌日に UQ WiMAX のコールセンターに電話して、「有償でいいので端末を購入したい。どうすればいいのか?」と問い合わせたのは私です。

# いや、他にもそれなりにいたみたいですけど。コールセンターの人、ぜんぜん困ってなかった風だし。

それ以来ずっと WiMAX を使い続け(端末は何回か変えた)、今いる場所に引っ越してからは固定回線を契約せず WiMAX だけの生活をしていた。それが先日、「今 WiMAX 2+ に乗り換えるといろいろ特典を付けるよ」みたいな案内が来たので、それに申し込んだのだ。

その、WiMAX 2+ の端末が昨夜届いた。NEC製の NAD11 というルータータイプの端末。

早速電源を入れたら「圏外」と表示されてアセったりしたが、しばらく放置したところ勝手に再起動して次からは普通に繋がるようになった。どうやら、初回起動時の自動処理をやっていたらしい。

が、その話は本題じゃない。

ウェブブラウザから端末の「クイック設定Web」と称する管理機能にアクセスして、いろいろと設定をしたわけだが、「ネットワーク設定」の中に「プロファイル設定」というものがある。説明書では「通信事業者の指示にしたがって設定せよ、普通は何も変えずに使え」みたいなことが書いてあるだけで詳しい説明は皆無。私は、コレに限らず情報通信機器は電源入れる前に取説を全部通して読む(いや、本当に)のだが、そのときにはこの機能は何も気にしていなかった。

ところが、実際にウェブブラウザに表示されると、最後の設定項目に「IPタイプ」というものがあり、「IPv4」になっている。しかも他の設定値はグレーアウトしていて変更できないようになっているのに、この項目だけ変更できるように見える。これは一体なんだろうと思って、設定を「IPv4&IPv6」に変更してみたところ、何か、唐突に、ウチの Windows PC の皆さんに、グローバルプレフィックスのIPv6アドレスが割り当たってしまったのですよ。ちょろっと調べたら、ウチの LAN には /64 の v6 アドレスが割り当たっていて、それで、おぉっと思って www.kame.net にアクセスしてみたら何事も無かったように亀が踊っていたという。

驚きました。

いや、よく考えたら、UQ コミュニケーションズという会社はKDDIの仲間で、KDDIというのは日本でもっとも v6 に熱心な第1種通信事業者だ(たぶん。実は良く知らないのだが。)そう思えば、新しい WiMAX で IPv6 が使えるというのは何も驚くようなことでは無かったのかもしれない。

でも、だったら一言教えてくれればいいのに。と、思った。

そう思って見直しても、NEC のウェブサイトにも、UQ のウェブサイトにも、IPv6 なんていう話は書いてない。いや、DNSが使えますとかICMPが使えますとか、そういうことも書いてないが、IPv6 はまだまだそういう「使えるのが当然」という状態ではないんじゃないかと思っているのだが。(でも Google で "NAD11 IPv6" で検索すれば、すでにいろいろ書いている人が見つかる。少しだけど。要は私が情弱ってことかも。)

3年ほど前に仕事で IPv6 をゴニョゴニョしたときには、v6 がちゃんと使える環境が身近になくて、dancing kame を見るだけでも非常に大変だった。自宅に KDDI の光ファイバーを引いていれば楽勝だなんていう話も聞いたが、身近にはそういう人はいなかった。

やはり世の中、われわれ一般人が気づかないところで、やるべきことを地道にやってくれている人たちというのはちゃんといるのだなぁ、なんて思った。

2014年9月23日 (火)

Taralli

業務スーパーで売ってたんですけど、名前だけ見て買いました。

Taralli

2014年9月15日 (月)

コドク・クロニクル(蠱毒伝奇?)

日本の伝承とクトゥルー神話の融合、だそうです。

ジャンルはゲームなのですがVisual Novelとも書かれており、まぁたぶんゲーム性は少なくて物語重視の作品なのでしょう。Yes/Noという選択を迫っている画面があったり、あと戦闘システムの説明もあったりするので、全くの一本道というわけでもなさそうです。

現在、kickstarterで出資者を募っており、わりとゆっくりと資金が集まっているようです。最初のゴールである8,000英ポンドには届くと思うのですが、それだと日本語版が出ないんですよね…。日本語版を作ってもらうには、20,000ポンド集まらないといけない。これは、結構苦しいんじゃないかと思いまして、極めて微力ながら、この場でも宣伝する次第です。

Db5408c8e41888ea825d9521c930f26a_la24ce1387a153e638f532ee70a65ab8e0_la

因みに下の画像のテキストは「ねぇ、正直に答えて。本当にここから逃げ出せると思ってる? はい - いいえ」みたいな感じですかね。

5ポンドから出資できますので、こういうの好きな方は、ぜひ。

Kodoku Chronicles by Carnivore Studio

https://www.kickstarter.com/projects/1347225956/kodoku-chronicles

2014年9月 8日 (月)

DotNetZipでEPUBファイルを作る

C#でEPUBファイル作ろうと思い、DotNetZipを使ってみた。

mimetypeを先頭に置いているのに、EPUBっぽくならない。ぐぐってみると、「EPUBではmimetypeは圧縮してはいけないが、DotNetZipは必ず圧縮する。そこで、適当なEPUBファイルを持ってきて、その先頭のmimetypeだけコピーして、云々」なんていう記事を発見。

いや、そんなことないでしょ、ZipEntry.CompressionMethodっていうプロパティがあって、これをNoneにすれば非圧縮メンバーを作れる。それでもEPUBにならなくて困ってるんだよ、こっちは、みたいな。

仕方ないので、ファイルを16進ダンプして良く見たら、ファイルヘッダーにextended fieldがついている。中身は「NTFS形式ファイルスタンプ」であった。

なるほど。

これを止めるには、ZipEntry.EmitTimesInWindowsFormatWhenSavingをfalseにすればよい。(Linux/Monoで動かすなら、ZipEntry.EmitTimesInUnixFormatWhenSavingをfalseにする。いちいちプラットフォームを調べる必要はなくて、常に両方ともfalseにしちゃうのが無難だと思う。)

つまり、こんな感じ。

    var mimetypeEntry = zipfile.Add("mimetype");
        mimetypeEntry.CompressionMethod = CompressionMethod.None;
        mimetypeEntry.EmitTimesInWindowsFormatWhenSaving = false;
        mimetypeEntry.EmitTimesInUnixFormatWhenSaving = false;

これで、cygwinのfile コマンドが"EPUB documen"と言ってくれるようになった。

2014年9月 6日 (土)

意味のわからないウェブの記載

楽天市場で買い物しようとすると、意味の全くわからない注意書きが多い。意図がわからないんじゃなくて、そもそも日本語の文として、何を言いたいのかさっぱりわからないのだ。

まとめWIKIみたいなものを読んでいても、意味のわからない文が多い。何を言いたいのかさっぱりわからない。

今まで、それは、文章を書いている人のセイだと思っていたのだ。要は、文章を書くのがヘタな人たちが書いた、意味がわかるように書けていない文章なんだと。ところが、今日、その中の一つのサイトが「記載が丁寧でわかりやすい」という評価を、複数の人たちから受けていることを知った。

おどろいた。

これはつまり、意味がわからないのは私が悪いということなんじゃないのか。普通の人が「わかりやすい」と感じる文章を、私は理解できないんじゃないのか。

なんというか、私は年寄りなのでありまして、実にプログラマ歴40年という年齢なわけですよ。たぶん、熱心にまとめWIKIなんかを書いている人たちとか、楽天市場に出店している店長さんたちの中心層とは、年齢がだいぶ離れている。同じ日本語とは言え、私の使う日本語とは、表現方法とかが違っちゃっているんではないか、などと思う次第。

# それが事実だとすると、たぶん逆も成立するので、自分ではわかりやすいつもりのこのブログも、今の若者には意味が全くわからない謎の文章でしかないのかもしれないなぁ、などとも思いつつ。

2014年8月12日 (火)

Office のマネージド COM アドインの DLL のバージョン番号

は、1.0.0.0 より大きくないといけないらしい。つまり、先頭を「0」にしてはいけないらしい。

これは、つまり、RegAsm で登録する DLL の VersionInfo に書くバージョン番号で、もともとは Visual Studio のプロジェクトのプロパティの Assembly Info... に書くバージョン番号だ。

これを 0.8.0.0 にしたら、Excel が、アドインの初期化を途中で止めて LoadBehavior を 2 に変更しちゃうようになってしまったのだった。(それに気づくのに4時間くらいかかったよ…。)

ウソでした。

バージョン番号だけ変えて試すと、0.X.X.X は全滅で、1.0.0.0 にすると動いたので、上に書いたような秘密の仕様があるのだと思い込んでしまったのですが、そういうことではありませんでした。

(原因不明のトラブルで苦しみ、午前0時ころにやっと動き、その後1時間ほどかけて原因の切り分けをして、ついにわかった、と思ってしまったわけです。一晩寝て、疲れが取れた頭でもう一度考えたら、おかしい気がしたのです。それを検証したら(昨夜はそこまでやらなかった;疲れていたので)やはりダメだったという…。ま、言い訳ですが。)

ということで、あいかわらず未解決なのですが、RegAsmとcodebaseとバージョン番号との関係がうまく行っていない(というか、たぶん私が何かを誤解している)のは間違いなく、Excelは無実だろうと、今は考えています。

と、いうことで、今回の教訓:「トラブルシュートが深夜まで長引いて、やっとうごいて『これで解決』と思っても、すぐブログに書かず、一晩寝て頭を冷やして翌日もう一回よく考えよう。」

追記

本件は、結局、アセンブリのバージョンが1.0.0.0以外の値だとRegAsmしたときに変なcodebaseレジストリエントリが作られてしまうというNetOfficeのバグに、私のテスト手順が悪かったことが複合したことによる謎動作だった、というのが、私の結論です。Excelは無実だと今は確信しています。

2014年6月21日 (土)

自作のXmlWriterをXslCompiledTransformにわたす

XmlWriterを自分で直接実装することはなくても、XmlTextWriterのサブクラスを作るのは、よくやりますよね。

あれ、やらない?変だなぁ。じゃぁ、みんな、こんなの作るときどうやってるんだろう。「セルの中で改行したいときには、コンテント(内容)中で普通に改行するんじゃなくて、
って書きなさい」っていう謎仕様なんですけど。あ、いや、上のリンク先には書いてありませんが。でも、そうなの。仕様なの。

単にLinq to XMLで書き出すだけなら何も問題ないんですけど、XSLTで処理した結果を自作XmlWriterで出力しようとしてハマったので、その回避方法を書いておきます。

自作したXmlWriterクラスのインスタンスを、いったん XmlWriter.Create(XmlWriter, XmlWriterSettings) にわたし、返ってきたインスタンスを XslCompiledTransform.Transform にわたす。これでOK。

ただし、注意点がひとつだけあって、それは、自作XmlWriterクラスのSettingsプロパティは、常にnullを返すようになっていなければいけない。まぁ、XmlWriterのSettingsのデフォルト実装は一律nullを返すので、そのままにしておけばいいだけなんですけど。

えー、なんちゅうか、ですね、これに気づくまで2ヶ月悩み続けた、という。XslCompiledTransformとXmlWriterの間には、公開されていない秘密のインターフェースがあって、一般人が使えるXmlWriterのサブクラスはそのインターフェースを使ってないので、XslCompiledTransformと組み合わせると激しく誤動作する(例えば、xsl:output で doctype-public 指定してるのに DOCTYPE 宣言が生成されないとか)というのはすぐに気づいたが、回避方法がわからなかったんですよ。まさか、XmlWriterSettingsに秘密の(internalの)プロパティがあって、そこにdoctype-publicが入っているので、XmlWriter側の責任でそのinternalのdoctype-publicを読み取って、XmlWriter.WriteDocTypeが呼ばれなくても正しいタイミング(つまり、文書ルート要素に対するWriteStartElementの直前)で勝手にDOCTYPE宣言を作らなければならない、なんていう仕様、これをなんとか実装しようとしていたんです。2ヶ月間。

でも、それはハズレの道だったんですね。

たぶん、マイクロソフトも、こんな仕様をクラスライブラリの外側で実装できるわけがないことはわかっていて、ちゃんと救済策を用意してくれていたわけです。それが、っていうか、そのためだけの目的で作られたと思われる XmlWriter.Create(XmlWriter, XmlWriterSettings) なわけです。

だったら、どうしてちゃんとドキュメントに書いておいてくれないんだ、せめてヒントだけでも、って思うわけですが、答えがわかってからドキュメント読んだら書いてありました。本当にヒントだけですが。

This method allows you add additional features to an underlying XmlWriter object.

訳:このメソッドにより、元のXmlWriterオブジェクトに追加機能を加えることができます。

この「additional features」っていうのが、XslCompiledTransformとXmlWriterとの間の非公開の様々なインターフェースの処理(上でかいたDOCTYPEの件以外にもたくさんある様子)ということを控えめに表現したものらしい。

うーん、なんちゅうかなぁ。

«使えないハッカー