watermint.org

Takayuki Okazaki's blog

Share on Facebook
Share on GREE
このエントリーをはてなブックマークに追加
はてなブックマーク - IllustratorとAdobe Distiller

昨日のGlassFish Night Seminar発表資料ですが、ようやくPDF化して公開することができました。「GlassFishで、作ってみた。」今回はずいぶんとIllustrator CS3と、Adobe Distiller 8、それにひょっとしたらMac OS X Leopardに苦しめられました。その苦労話を・・。
Illustrator and Distiller
まず、昨日の段階で資料をPDFに変換しようとしたら、Adobe PDFプリンタがいっこうに動き始めません(というか、動き始めてすぐ止まる)。何回やっても一時停止になるし、テストページの印刷でも同じだし、Firefoxなど別のアプリケーションから印刷しても同じだったのでこれはIllustratorではなくて明らかにAdobe PDFプリンタ、つまりAdobe Distillerの問題でした。EPSONのプリンタへはふつうに印刷できましたのでOSのプリントスプール側の問題でもなさそうです。
Illustrator and Distiller
強引にスプール上のジョブを再開しようとすると上図のように、Operation Could not be completed.とエラーになり全く進みません。Mac OS Xシステム環境設定の「プリントとファックス」でAdobe PDFプリンタを削除してから登録し直してもだめ。システム環境設定で削除しておいて、Adobe Acrobat Professionalのメニューで「ヘルプ」→「Acrobat インストールの修復」でPDFプリンタを入れ直してもだめ。しょうがなく、Adobe Acrobat Professionalを再インストールしてみましたがそれでもだめ。
Illustrator and Distiller
途方に暮れている頃に思いついたのがコンソールのエラーログを見ること。そうすると思惑通り、というかやっぱりDistillerがコケていることがわかりました。DistillerのCrash Reportをみると原因はSIGBUSで、常にThread 2がこけていました。Thread 2はCrash Reportのスタックトレースによると

Thread 2 Crashed:
0   com.adobe.DistillerLib        	0x01147b80 DistillerFontFolders::GetFontCachePath(char**) + 32
1   com.adobe.DistillerLib        	0x01157695 DistillerPSRip::SetupPSParameters() + 767
2   com.adobe.DistillerLib        	0x01157aba DistillerPSRip::PSInit(void*) + 224
3   ...ple.CoreServices.CarbonCore	0x90662d41 CooperativeThread + 309
4   libSystem.B.dylib             	0x93a176f5 _pthread_start + 321
5   libSystem.B.dylib             	0x93a175b2 thread_start + 34

というようにGetFontCachePathという関数で毎回こけているようです。海外のフォーラムで同様の現象を報告している人の中で、$HOME/Library/Application Support/Adobe/ 以下にあるFontCacheディレクトリのパーミッションを変えたら直ったという人がいて、試してみましたがだめでした。もっといろいろ情報集めをしていたところAcrobatの8.1.2アップデートに更新しろと書いている人がいました。Creative Suiteを入れたときに2〜3回Adobe Updaterでアップデートしていたので当然Acrobatも更新されているものだろうと思っていましたが、バージョンを確認したら意外にも8.0.0・・・。
Illustrator and Distiller
Adobe Updater、どこみとってん!一言愚痴を言わせてもらうと、Adobe Updaterの品質の低さは異常です。品質というか、ユーザアンフレンドリーさは、たくさんあるアップデートセンター系システムの中でも最低だと思います。まあ、そんな愚痴を心の中でつぶやきながらアップデート。
Illustrator and Distiller
毎回Safariのプラグインを入れるかきかれますが、ブラウザ中にPDF表示するのって大嫌いなので必ずオフにしています。Acrobatを入れて最初にやることはブラウザ上に表示させないように設定することです。Mac OS XのPreviewもSafari内にいたがりますが、

$ defaults write com.apple.Safari WebKitOmitPDFSupport -bool true

というようにdefaultsコマンドで設定をオフにしています。さて、Acrobat 8.1.2にアップデートしたことでようやくDistillerが快調に動き始めました。テスト印刷もばっちりです。では、Illustratorで・・・。
Illustrator and Distiller
あれ?各ページが1/2のサイズになって、しかも前後のページが半分ずつ各ページに入っています。2ページ目には1ページ目と3ページ目の上下が、3ページ目には2ページ目と4ページ目の上下が・・・。なにこれ。
Illustrator and Distiller
Illustrator上では今回、ドキュメントサイズは幅297mm、高さ4200mm (A4横の用紙を縦方向に20枚並べた大きさ)に設定し、プリントの設定として用紙サイズA4横、セットアップでタイルに「用紙サイズで区分ける」、トンボと裁ち落としで裁ち落としを天地左右 0mmとしてページ分割されるように設定しました。あとはメニューの「表示」→「ページ分割を表示」とすれば印刷サイズにあった罫線が表示されそのようにデザインしやすくなります。ページ分割が表示されているとおり印刷結果が得られるだろうと考えていましたし、実際Tigerで使っていた頃はそう結果がえられたので何も疑問なくやっていましたが、いざおかしくなるとどうしていいかわかりません。
Illustrator and Distiller
結局悩みに悩んでうまく行った方法が、プリンタをAdobe PDF 8.0ではなく、Adobe PostScriptファイルとして、PostScriptでの結果をまず得て、その結果をAdobe DistillerでPDFに変換する方法です。Adobe PDF 8.0プリンタも中身はDistillerのはずなので、釈然としませんが、とりあえずうまくいったのでこれでよしとします。そもそも、複数ページ(しかも20ページとか・・)のデザインをIllustratorでやることはあまり想定されていないのでしょうがないところですね。ああ・・InDesignがほしい。そういえば、Creative Suite 4が発売になりましたが、InDesignやAfter Effects・Premiereを含むMaster Collectionへのアップグレードが今持っているCreative Suite CS3 Web Premiumからだと$1,199なんですよね・・・。日本での値段はまだわかりませんが、ちょっとほしくなってきました。

Share on Facebook
Share on GREE
このエントリーをはてなブックマークに追加
はてなブックマーク - 過去のプログラムで昔を懐かしむ

懐かしむシリーズ(?)第二弾です。いろいろ昔のファイルを整理していると、懐かしいプログラムが出てきました。高校の頃はやたらアセンブラとかを使ってグラフィックライブラリなんかを再実装するのにやたら時間を費やしていました。

/*
 * PC-9821 256color graphics library
 * $Id: dos256.c 1.1 96/02/03 22:14:27 Okazaki Exp Okazaki $
 */

RCSのログも残っていました。12年半前のプログラムですね。でもこれ以外にも何回か作り直した記憶があります。これはPC-9821のMS-DOS専用グラフィックライブラリで、PC-9801では4096色中16色しか使えなかったのが、PC-9821では16777216色(24ビット)中256色を使うことができる拡張がありました。このプログラムはその拡張を利用するためのプログラムです。

#include "dos256.h"

void dos256begin(void)
{
	_asm {
		mov		al,07h
		out		6ah,al
		mov		al,21h
		out		6ah,al
		mov		al,0dh
		out		0a2h,al
	}
}

void dos256end(void)
{
	_asm {
		mov		al,07h
		out		6ah,al
		mov		al,20h
		out		6ah,al
	}
}

もうほとんど中身はアセンブラです。この辺は文献を参考にしながら淡々と打ち込めばいいだけです。

void dos256cls(void)
{
	_asm {
		mov	ax,0e000h
		mov	es,ax
		mov	bh,0
		mov	bl,1
		mov	es:[0004h],bh
		mov	es:[0006h],bl
		mov	cx,16384
		xor	di,di
		mov	ax,0a800h
		mov	es,ax
		xor	eax,eax
		rep	stosd

		mov	ax,0e000h
		mov	es,ax
		add	word ptr es:[0004h],2
		add	word ptr es:[0006h],2
		mov	cx,16384
		xor	di,di
		mov	ax,0a800h
		mov	es,ax
		xor	eax,eax
		rep	stosd

		mov	ax,0e000h
		mov	es,ax
		add	word ptr es:[0004h],2
		add	word ptr es:[0006h],2
		mov	cx,16384
		xor	di,di
		mov	ax,0a800h
		mov	es,ax
		xor	eax,eax
		rep	stosd

		mov	ax,0e000h
		mov	es,ax
		add	word ptr es:[0004h],2
		add	word ptr es:[0006h],2
		mov	cx,14848
		xor	di,di
		mov	ax,0a800h
		mov	es,ax
		xor	eax,eax
		rep	stosd
	}
}

画面をクリアするための関数ですが、一応、32ビットレジスタを使って4バイトずつ画面をクリアしているので少しは速いです。そういえば、当時はBorland C++ 4.0とTurbo Assemblerを使っていたと思います。

void dos256pixel(int x, int y, int c)
{
	unsigned long	adr;
	unsigned short	vadr;
	unsigned short	ioadr;
	unsigned char	col = c & 0xff;

	if (x >= 0 && x < 640 && y >= 0 && y < 640) {
		adr 	= (long)y * 640L + x;
		vadr	= (unsigned short)(adr & 0x7fff);
		ioadr	= (unsigned short)(adr >> 15);

		_asm {
			mov		ax,0e000h
			mov		es,ax
			mov		ax,04h
			mov		si,ax
			mov		ax,ioadr
			mov		es:[si],ax
			mov		ax,0a800h
			mov		es,ax
			mov		ax,vadr
			mov		si,ax
			mov		al,col
			mov		es:[si],al
		}
	}
}

アドレスを計算してドットをうちます。これも淡々と打ち込めばいいだけ。

void dos256palette(int c, int r, int g, int b)
{
	unsigned char col = c & 0xff;
	unsigned char cr = r & 0xff;
	unsigned char cg = g & 0xff;
	unsigned char cb = b & 0xff;

	_asm {
		mov		al,col
		out		0a8h,al
		mov		al,cg
		out		0aah,al
		mov		al,cr
		out		0ach,al
		mov		al,cb
		out		0aeh,al
	}
}

パレットの変更。フルカラーが当然の今だとあんまり使わないかもしれませんが、GIF画像なんかをPhotoshop等で扱ったことのある方ならインデックスカラーとしておなじみかもしれません。

void dos256line(int x1, int y1, int x2, int y2, int c)
{
	int dx, dy;
	int s;
	int step;

	dx = x2 - x1; if (dx < 0) dx = -dx;
	dy = y2 - y1; if (dy < 0) dy = -dy;

	if (dx > dy) {
		if (x1 > x2) {
			step = (y1 > y2) ? 1 : -1;
			s  = x1; x1 = x2; x2 = s; y1 = y2;
		} else {
			step = (y1 < y2) ? 1 : -1;
		}
		dos256pixel(x1, y1, c);
		s = dx >> 1;
		while (++x1 <= x2) {
			if ((s -= dy) < 0) {
				s += dx;
				y1 += step;
			}
			dos256pixel(x1, y1, c);
		}
	} else {
		if (y1 > y2) {
			step = (x1 > x2) ? 1 : -1;
			s  = y1; y1 = y2; y2 = s; x1 = x2;
		} else {
			step = (x1 < x2) ? 1 : -1;
		}
		dos256pixel(x1, y1, c);
		s = dy >> 1;
		while (++y1 <= y2) {
			if ((s -= dx) < 0) {
				s += dy;
				x1 += step;
			}
			dos256pixel(x1, y1, c);
		}
	}
}

線を引くところはブレゼンハムのアルゴリズムです。これもどこかの本に載ってたのを淡々と写経しているような感じです。ブレゼンハムのアルゴリズムが載っている本を参照しているなら、円とかも実装してもよさそうな気がしますが、使わない物は実装しない主義だったようですね。そういえば、画像系でいうと、いかに画面を素早く塗りつぶすかでいろいろ試行錯誤した後が見つかりました。フルアセンブラ実装とか。

code	segment
	assume	cs:code,ds:code,ss:code
	org	100h

start:
	; extended graphics start
	.186
	mov	al,07h
	out	6ah,al
	mov	al,21h
	out	6ah,al
;	mov	al,06h
;	out	6ah,al

	mov	al,0dh
	out	0a2h,al

;	mov	ax,0e000h
;	mov	es,ax
;	xor	al,al
;	mov	es:[0100h],al
;	xor	ax,ax
;	mov	es,ax
;	mov	al,80h
;	or	es:[054dh],al

	; display hsync 31kHz
	mov	ah,31h
	int	18h
	and	al,04h
	jnz	hsyncend

	; display hsync 24kHz -> 31kHz
	mov	ah,30h
	mov	al,00001100b ; hsync 31kHz
	mov	bh,00010001b ; 640x200(upper), text 25line mode
	int	18h
hsyncend:

	; clear screen
	; erase bank 0 to 7
	mov	bh,0
	mov	bl,1
	call	erase

	; erase bank 8 to 15
	mov	bh,8
	mov	bl,9
	call	erase

	; extended graphics end
	mov	al,07h
	out	6ah,al
	mov	al,68h
	out	6ah,al
	mov	al,20h
	out	6ah,al
;	mov	al,06h
;	out	6ah,al

	mov	al,0ch
	out	0a2h,al
;	mov	al,0dh
;	out	6bh,al

	xor	ax,ax
;	mov	es,ax
;	mov	al,7fh
;	and	es:[054dh],al

	; quit
	mov	ax,4c00h
	int	21h

erase:
	.386
	mov	ax,0a800h
	mov	es,ax
	mov	ax,0e000h
	mov	fs,ax
	xor	eax,eax

	mov	fs:[0004h],bh
	mov	fs:[0006h],bl
	mov	cx,16384
	xor	di,di
	rep	stosd

	add	word ptr fs:[0004h],2
	add	word ptr fs:[0006h],2
	mov	cx,16384
	xor	di,di
	rep	stosd

	add	word ptr fs:[0004h],2
	add	word ptr fs:[0006h],2
	mov	cx,16384
	xor	di,di
	rep	stosd

	add	word ptr fs:[0004h],2
	add	word ptr fs:[0006h],2
	mov	cx,14848
	xor	di,di
	rep	stosd
	ret

code	ends
end	start

mov ax,4c00h と int 21hなんかは呪文のように覚えてた記憶がよみがえりました。こんな感じでアセンブラにはまってた時期もありましたが、図書館に行ってもなかなかTurbo Assemblerの本はなくて、MASMの本をみて、Turbo Assembler的に書き換えるということをしてたような気がします。