MingとはFlashファイルを出力するライブラリで、 最近ではFlex2MTASCなどに押され気味な気がしないでも無いが、 フォントの埋め込みができるというのと、C/C++から直接ストリームにSWFファイルを出力できるというところがヨサゲだったので、ちょっと触ってみる。

マニュアル

http://www.libming.org/docs/libming/index.html http://www.libming.org/docs/perl/index.html

コンパイル

VCのプロジェクトから0.3.0のDLLを作ろうとしたが、ファイルポインタをDLLに渡すところで落ちる。MinGWでビルドしたものも、VC6からリンクすると同じ問題にはまって解決できなかったので、仕方が無いので静的ライブラリとして作成した。
結局日本語フォントを使うと落ちるのは変わらず。仕方が無いのでVCを諦めて、完全にMinGWでコンパイルすることにしたらあっさり通った。最初からこうすればよかった。

ついでにPukiwikiのFlashプラグインも入れてみたよ

自作プラグイン/flash.inc.php - Pukiwiki-official

Sample1

#include <stdio.h>
#include "ming.h"

#define FONT_FILE "Sazanami Mincho.fdb"
#define WIDTH  300
#define HEIGHT 200
#define SIZE   40

int main()
{
	const char str[] = "こんにちは";
	FILE *f;
	SWFFont font;
	SWFText text;
	SWFDisplayItem d;
	SWFMovie movie = newSWFMovie();

	SWFMovie_setDimension(movie, WIDTH, HEIGHT);
	SWFMovie_setBackground(movie, 0x33, 0x44, 0x33);
	SWFMovie_setRate(movie, 12);

	f = fopen(FONT_FILE, "rb");
	if (f == NULL) {
		printf("failed to open font file!\n");
		return 1;
	}
	font = loadSWFFontFromFile(f);
	text = newSWFText();
	SWFText_setFont(text, font);
	SWFText_setColor(text, 0xff, 0xff, 0xff, 0xff);
	SWFText_setHeight(text, SIZE);
	SWFText_setSpacing(text, 0);
	SWFText_addUTF8String(text, str, NULL);
 	d = SWFMovie_add(movie, (SWFCharacter)text);
	SWFDisplayItem_move(d, 10, 100);

	SWFMovie_save(movie, "ming_test01.swf");
	return 0;
}

日本語

0.3.0には文字を表示するための三つの関数がある。

で、日本語を使う場合、addUTF8StringかaddWideStringのどっちかを使わなければならない。ところで、UTF-8をWideStringに変換するコンバーターがmingw-0.3.0/src/blocks/utf8.cにあるので、文字列を一文字ずつループするときはUTF-8をを長さが固定のWideStringに変換した方が便利だ。

埋め込みできる日本語TrueTypeフォント探し

Mingでシンボルを作ってActionScriptでインスタンス生成

Flashのオーサリングツール上、シンボルとインスタンスと呼ばれているものは、Mingでは、インスタンスはSWFDisplayItemと呼ばれ、シンボルはSWFMovieClipらしい。SWFMovie_addExportを使ってMovieClipにリンケージ識別子をつけてシンボル化する。SWFShapeとかはダメでSWFMovieClipしかシンボル化できないようだ?

#include <stdio.h>
#include <ming.h>

#define WIDTH  300
#define HEIGHT 200
#define STRINGIZE1(s) #s
#define STRINGIZE(s) STRINGIZE1(s)

int main()
{
	SWFMovie movie = newSWFMovie();
	SWFShape shape = newSWFShape();
	SWFMovieClip mc = newSWFMovieClip();
	SWFFill fill;
	SWFAction action;

	SWFMovie_setDimension(movie, WIDTH, HEIGHT);
	SWFMovie_setBackground(movie, 0xff, 0xff, 0xff);
	SWFMovie_setRate(movie, 12);

	SWFShape_setLineStyle(shape, 100, 0x00, 0x00, 0xff, 0xff);
	fill = SWFShape_addSolidFill(shape, 0x00, 0xff, 0xff, 0xff);
	SWFShape_setLeftFill(shape, fill);
	SWFShape_movePenTo(shape,   0,  0);
	SWFShape_drawLineTo(shape, 30,  0);
	SWFShape_drawLineTo(shape, 30, 30);
	SWFShape_drawLineTo(shape,  0, 30);
	SWFShape_drawLineTo(shape,  0,  0);

	SWFMovieClip_add(mc, (SWFBlock)shape);
	SWFMovieClip_nextFrame(mc);
	SWFMovie_addExport(movie, (SWFBlock)mc, "square");

	action = compileSWFActionCode(
			"for (var i = 0; i < 30; i++) {\n"
			"	var name = 'square' + i;\n"
			"	_root.attachMovie('square', name, i+1);\n"
			"	_root[name]._x = Math.random() * " STRINGIZE(WIDTH) ";\n"
			"	_root[name]._y = Math.random() * " STRINGIZE(HEIGHT) ";\n"
			"}\n"
			);
	SWFMovie_add(movie, (SWFBlock)action);

	SWFMovie_save(movie, "ming_test02.swf");
	return 0;
}

ところでどうやってデバッグするんですかね……

traceを埋め込むことはできようようだが、FlashMXから実行してみても出力されないみたいなんですが。

int create_debug_trace (SWFMovie *movie)
{
	SWFAction action;
	SWFTextField   text = newSWFTextField();
	SWFBrowserFont font = newSWFBrowserFont("_serif");
 	SWFTextField_setBounds(text,300,50);
	SWFTextField_setFlags(text, 
			SWFTEXTFIELD_WORDWRAP
			| SWFTEXTFIELD_MULTILINE
			| SWFTEXTFIELD_AUTOSIZE );
	SWFTextField_setFont(text,(SWFBlock)font);
	SWFTextField_setVariableName(text, "log");
	SWFMovie_add(movie,(SWFBlock)text);

	action = compileSWFActionCode(
			"var log = '';"
			"function dump(x) {\n"
			"	log += x + '\n';"
			"	log.scroll = log.maxscroll;\n"
			"};\n"
			"dump('*** DEBUG DUMP ***');\n"
	);
	SWFMovie_add(movie, (SWFBlock)action);
	return 0;
}

色々言いたいことはあるが、(ありません)とりあえずこんな感じでTextFieldに出力することにした。ActionScriptからdump("log message")する。本当はTextFieldの生成もActionScriptから

createTextField('log', 1, 0, 0, 200, 50);
log.text = "debug message";

みたいにしたかったのだが、どうしてもこれができなかった。原因不明(0.3.0)。同じコードでもFlash MXから問題なく表示できるのでmingのコンパイラのバグのような気がしないでもない。よくわからない。あとでmingの0.4b3を試してみるかもしれない。原因がわかった。原因は

int main()
{
	SWFMoive movie = newSWFMoive();
	Ming_useSWFVersion(6);
}

のように、Movie生成をSWFのバージョン定義をする前にしていたことだった。ソースを追っかけてて気がついた。まず最初にMing_useSWFVersionでバージョンを決めてから様々なオブジェクトを生成しなければならないようだ。それで結局上のコードは破棄して、こんな風にした。

int create_debug_dump (SWFMovie *movie)
{
	SWFAction action;
	action = compileSWFActionCode(
			"createTextField('log',  0xFFFFFFFF, 0, 0, 300, 100);\n"
			"log.type = 'input';\n"
			"log.multiline = true;\n"
			"log.variable = 'logmsg';\n"
			"function dump(x) {\n"
			"	logmsg += x + '\n';\n"
			"	logmsg.scroll = logmsg.maxscroll;\n"
			"};\n"
			"dump('*** DEBUG DUMP ***');\n"
			);
	SWFMovie_add(movie, (SWFBlock)action);
	return 0;
}

コメントをどーぞ



CategoryFlash


|New|Edit|Freeze|Diff|History|Attach|Copy|Rename|
Last-modified: 2008-04-14 (Mon) 18:01:13
HTML convert time: 0.013 sec.