会社に集まって何か書いたりする日.所謂ハッカソン.
ノートPC二台並べて,Scalaのビルドやテストを待ってる合間に,rubyとsinatraで何か作ったりする.コンパイル遅い.
*[scala] WindowsのPlay Frameworkのsbt出力をまともにする
会社のPCがWindowsなので.Macとかいうもあるらしいのですが,宗教上の理由で使うことができないのです.
VM上のLinuxとかで開発する人も多いと思いますが,Scalaコンパイラがとても重いので,VM上よりWindows上で実行して少しでもビルドを早くしたいです.
とりあえずplayをWindowsで動かしてみると困るのが,
この2点です.
sbtを0.13にすれば色がつくし,sbtのjavaのオプションで-Dfile.encoding=SJISとかすれば,日本語も表示されるのだけど,playが内部的に使っているsbtは0.12なのと,sbtのエンコーディングを設定でどうにかする方法が見当たらない.
どうせ将来的のバージョンでは必要なくなるのだろうけど,一応メモっておく.
文字コードをどうにかする
みんな,色々な方法で解決していると思いますが,一長一短という感じ.
このために,build.scalaとかにいろいろ入れて汚したりはしたくない.
chcpでコマンドプロンプトの文字コード変えるのが真っ当っぽい解決方法ですが,フォントの設定っが面倒だったり,たまに表示がおかしくなるのと,ckwのような別のコンソールを使ってる場合など使えない場合があります.
結局,nkfで出力を変換することにしました.こういうとき,バッファリング無効にできるnkfがいまだに役に立つ.
色をつける
色については,sbtがjlineというライブラリを使っているようで,ターミナルの設定がWindowsTerminalになっていると,ANSIのエスケープシーケンスを消してしまう.
UnixTerminalにすると,とりあえず出力されるが,バッファリングがおかしくなるのか,エンターキーを押したあと,一瞬間があくのがつらい.
UnsupportedTerminalは何もしないと書かれているけど,エスケープシーケンスをそのまま出力してくれるようだし,変な動作もしないので,これが良さそう.
近頃のWindowsのコマンドプロンプトは,ANSIのエスケープシーケンスとか無視するので,wacを使って色を付ける.
build.bat
nkf32.exe と,wac.exe は適当にパスの通ったところにおいておく.
playのframework/build.batも以下のように書き換えて,
nkf32 -u -Lu -S -w | java -Djline.terminal=jline.UnsupportedTerminal ~省略~ -jar "%~dp0sbt\sbt-launch.jar" %* | nkf32 -u -W -s | wac
文字化けもしないし,色もちゃんとついた.
書くことが無いときは,食べ物の写真載せればいいのか.
昼.食パンでかい.お腹いっぱいになった.
銀座のせいで,エンゲル係数が跳ね上がっている気がする.しばらく,はなまるうどんとかにするか.
寿司食べた.
仕事の後,おなかへったので築地の方へ.夜中も開いてる店もあるにはあるのか.
L,R,T,P
WHRETEIRU HWHREN OREKUTOWI KENERH
なんだろ...
safii,gazyu,kmuroiと渋谷駅で待ち合わせ.
チャットのログがひどかった.
「西口ついたー」
「ついたー西口むかう」
「もうすぐつく」
「西口にいるんだが」
「まだ恵比寿駅・・・」
「南の方の出口にいるよ」
「首都高の下」
「よりは北だけども」
「safiiがいない。。。」
「東口にいた」
「結局どこなんだw」
「東が正解」
「どうみても東です」
「ひどいトラップですね(笑)」
Google Latitudeが終わってしまったのも原因...
渋谷で食べた牛かつが美味しかった.
ヒカリエでケーキ食べて,ビックカメラでタブレット物色して,東急ハンズで色々遊んで,紀伊国屋で本を買う.
夜は京都っぽい何か食べた.
機械学習の勉強しないとなーと思いながら,本だけ積まれてるのどうにかしないとだ.
Play frameworkのWebSocketはPINGフレームとかには対応してないのかな.FrameFormatterとか自分で作るべきなのかもしれないけど,よく読んでないので分からない.
昨日はPDFの仕様書読んでいたので,せっかくなので実装してみる日.
*PDFのテキストをレンダリングするための最小限の実装
多少のレイアウトの崩れには目をつぶって,それっぽく,テキストをレンダリングする.
PDFの仕様書のAPPENDIX Aにある「Operator Summary」を見て,重要そうなのから実装していく.
Q BT /CS0 cs 0 0 0 scn /T1_0 1 Tf 9.4 0 0 9.4 51.005 537.89 Tm (8)Tj ET 1.02 w q
こんな文字列がContentsのストリームに入っています.各トークンは空白文字で区切りますが,「(8)Tj」のように明らかに分離できる場合は,スペースを入れなくても構いません(このあたりはPDF全体でそうなってます).
PDFはPostScript由来の後置記法を採用しているので,例えば,Tmの引数はその前にある6個の数値です.
cm,Q,q
グラフィックス系のオペレーターとして書かれているけど,座標変換はテキストにも影響する.
cmで与えられた行列は回転を無視するなら,位置とスケールとして覚えておけば大丈夫.
Q,qでグラフィックスのステートをスタックにpushしたりpopしたりする.
BT,ET
BTでテキスト関係の行列を初期化.ネストしないらしいので,ETは無視しててもとりあえず動きます.
Td,TD,TL,Tf,Tm,T*
このへんはサポートしないとまともに位置が合わない.
話は変わるけど,字句解析から自前でやってたら,T*とかいうオペレータがあったの忘れてて,少し面倒くさかった.
Tj,TJ
Tjは1つの文字列を描画する.TJは文字列の間に位置のオフセット情報が入った配列を受け取り,描画.
ここまでできた
自炊本リーダー(仮)に実装してみて,今まで真っ白に表示されてた普通のPDFを開いてみたところ.CIDのマッピングは,Adobe-Japan1に限定.UnicodeとCIDのマッピングはフォントが持って居そうだけど,AndroidのAPIにはそれっぽいのが無いのでアプリ側で持つことに.
とりあえず表示はできましたが,
-
文字のレンダリングはdrawText呼んでるだけなので,文字が重なっている箇所がある
-
一部の記号が化けている
-
実装してないので画像は表示されない
-
実装してないので図形や色も無い
のでまだダメっぽいですね.
あとは,表示できる画像リソースが見つからない時に,テキストのレンダリングを試みているので,表示速度に影響を与えない代わりに,サポートされている画像が入ったページはその画像だけ表示されてしまう.
PDFの勉強のため内部のテキストを抜き出すプログラム書いたりする.
PDF内のテキストは複雑なので,あまり扱いたくなかったのだけど,そろそろ,自炊本リーダ(仮)でテキスト表示したい.既存のPDFライブラリ使えば良いのだけど.
AdobeのPDFの仕様書と,実際のPDFを見比べながらいろいろ.
*PDF内のテキスト
PDF内のテキストデータは
(Hello)
とか
<037003b103ab03b103ab0c880358>
のような感じに入っています.(ほとんどの場合)英数字はそのまま入ってますが,日本語は謎の16進数が並んでいます.
Font
PageオブジェクトのResources下に,FontというDictionaryがある.そのなかにF1,F2,F3…という名前でフォント情報が列挙されている.
PDFの文字列は,エンコーディングの情報もFontに入っています.なのでFontをどうにかしないと,文字列を取得することすらできません.UTF-8とかなら良いのだけど,大抵はフォントのCIDが書かれています.
Font/Encoding
日本語のPDFでよく見るのは下の2つ.
-
Identity-H CID (縦書は-V)
-
90ms-RKSJ-H ShiftJIS (縦書は-V)
Font/DescendantFonts/CIDSystemInfo
Registry, Ordering, Supplementが入っている.
例えば,
-
Registry: Adobe
-
Ordering: Japan1
-
Supplement: 2
Orderingごとに,どのCIDがどの文字に対応するかのマッピングはAdobeが公開している.
ToUnicode
EncodingがIdentityのとき,CIDとUnicodeのマッピングが書かれている.中身はたまに見かけるCMapファイルそのままっぽい.あまり見かけない.
ICFPC終わった.結果は微妙.メモリが1TBくらいあれば.
今日は会社に行かないとなので,9時から昼まで寝る.
寝不足すぎるので,「眠いので夕方行きます」と連絡して(というかFacebookに書いて)もう少し寝る.
結局,風邪引いたっぽくて「体調崩したので,明日行きます」と連絡する.
ダメな感じの社会人の行動っぽい.溜まったアニメも見ないとだし.メールとかも溜まってるし,憂鬱になる.
やっぱ,他の一切のことを気にせず何かやるのが良いなあ.
ペットボトルを見て,コーラを飲み過ぎた気がしてきた.
ICFPC
スコアは不調.方針が間違ってる気がしないでもないけど,そのまま行く.
問題を解くプログラムが,メモリを10GB以上食っててOSの挙動が怪しくなる.
この3日,ピザと寿司を食べた以外は,全部コンビニの食料と,コーラで生きている気がする.
ICFPC
eldeshが来た.
ピザ食べた.
とても暑い.
朝から,ICFPC.今回はうちでやる.
今年はわりと分かりやすい問題.どうやって解くのかはまったく思いつかないけど.
未知のプログラムがあって,1つのプログラムにつき,5分以内に,入力に対する出力から,中身を推測しろという問題っぽい.
lambda, fold, if ,0, 1と演算子いくつかという,わりと普通っぽい言語.
コンテストのサーバのAPIを呼び出して/evalで与えた引数の実行結果を見て,/guessで推測したプログラムを送ると,正解か,ダメなら判例となる引数と結果のペアを一つ返してくれる.5分以内なら何回か試行できるけど,20秒間に5回以上叩くとrequest too manyと怒られるので,適度にsleep入れないといけない.何年か前に,サーバが重すぎて回答がなかなか提出できないことあったけど,今回は大丈夫そう.
関数のサイズ(ワード数)はAPI叩くと取得できるので,とりあえず簡単なやつだけ選んで60個くらい解いてみる.
今日は,APIを叩くためのクライアントとか,計算したときにいろいろする怪しいライブラリとかを作る.
寿司食べた.
夜,eldeshを呼んだが来てくれなかった.残念.
飲み会.
自炊本リーダ(仮)で,PDF内のDictionaryデータの解析を正規表現でやっていて,遅いし意味不明になってきたので,普通に書きなおす.
ちょっとだけ速くなったけどファイルからデータを読む時間がほとんどだからこれ以上は速くならなそうだなあ.あとは表示周りで,RenderScriptで処理した結果をメモリ上のビットマップにコピーしてそれをImageViewにセットするという非効率的なことやってしまっているので,TextureViewにOpenGLで描画するようにするか...
仕事中だったけど,飲み会に誘われたので目黒に行く.