gcj/23


gcj

こんにちわ、世界

モナーフォントを読み込んで表示してみる。モナーフォントとはAAを表示するために作られたフリーのプロポーショナルフォント。

FontMetrics.java

実際のフォントの読み込みはCNIで行う。オフセットの辺りはBayGUIのぱくりです・・。

	private native void create(byte[] data);

	/** コンストラクタ */
	public FontMetrics() {
		this.fontStyle = Font.PLAIN;
		if (defaultFontData == null) {
			this.defaultFontData = new byte[167921];
			create(this.defaultFontData);
		}
		
		offsetListLength = (defaultFontData[1] & 0xFF) << 8 | defaultFontData[0] & 0xFF;
		
		// 文字までのオフセット(byte)
		offsetList = new int[65536];
		
		// オフセットリストを作る
		int pos = 4;
		for (int i = 0; i < offsetListLength; i++) {
			offsetList[(defaultFontData[pos + 1] & 0xFF) << 8 | defaultFontData[pos] & 0xFF] = pos;
			pos += 4;
			int fw = defaultFontData[pos++] & 0xFF;
			int fh = defaultFontData[pos++] & 0xFF;
			pos += (int)((fw * fh + 7) / 8);
		}
	}

FontMetrics.cpp

実際のフォントの読み込みを行う部分。GUIサーバーから取得してもいいし、fopenで取得してもよい。

#include <java/awt/FontMetrics.h>
#include <gcj/cni.h>
#ifdef MONA
#include <monapi.h>
#include <monapi/messages.h>
#endif

void
java::awt::FontMetrics::create (jbyteArray data)
{
	//data = (jbyteArray)_Jv_NewPrimArray(&_Jv_byteClass, mi->Size);
	jbyte* data_p = elements(data);
#ifdef MONA
	monapi_cmemoryinfo* mi = monapi_call_file_decompress_st5_file("/MONA12.MF5", false);
	if (mi == NULL || mi->Size == 0) return;
	memcpy(data_p, mi->Data, mi->Size);
	monapi_cmemoryinfo_dispose(mi);
	monapi_cmemoryinfo_delete(mi);
#endif
}

Main.java

とりあえず java.awt.Graphics.drawString() の中身を実装してみる。中身はBayGUIのぱくりです・・。

import java.awt.Font;
import java.awt.FontMetrics;

public class Main {
	private static final int SCREEN_W = 200;
	private static final int SCREEN_H = 100;
	int[] pbuf;
	
	public void drawPixel(int x, int y) {
		pbuf[SCREEN_W * y + x] = 0xff000000;
	}
	
	public void drawString(String str, int x, int y) {
		int pos, bit, offset, width, height, w = 0, h = 0;
		byte[] fp = new byte[256];
		
		// nullチェック
		if (str.length() == 0) return;
		
		FontMetrics fm = new FontMetrics();
		int I = str.length();
		for (int i = 0; i < I; i++) {
			pos = 0;
			bit = 1;
			char ucs4 = str.charAt(i);
			// 改行
			if (ucs4 == '\n') {
				w = 0;
				h += 12;
			}
			if (fm.defaultFontData != null && fm.offsetList[ucs4] != 0) {
				int fw = fm.defaultFontData[fm.offsetList[ucs4] + 4];
				int fh = fm.defaultFontData[fm.offsetList[ucs4] + 5];
				// オフセットを計算する
				if ((fm.getFontStyle() & 0x100) == Font.FIXED) {
					if (ucs4 < 128 || 0xff60 < ucs4) {
						offset = 6;
					} else {
						offset = 12;
					}
				} else {
					offset = fw;
				}
				width  = fw;
				height = fh;
				// fp にフォントデータを展開する
				int J = (fw * fh + 7) / 8;
				for (int j = 0; j < J; j++) {
					fp[j] = fm.defaultFontData[fm.offsetList[ucs4] + 6 + j];
				}
				// フォントを実際に描画する
				for (int j = 0; j < height; j++) {
					for (int k = 0; k < width; k++) {
						int x0 = x + w + k + (offset - width) / 2;
						// 行パディングなし
						if ((fp[pos] & bit) != 0) {
							drawPixel(x0, y + h + j);
						}
						bit <<= 1;
						if (bit == 256) {
							pos++;
							bit = 1;
						}
					}
				}
				w += offset;
			}
		}
		SimpleCanvas.doEvents();
	}
	
	public void repaint() {
		pbuf = new int[SCREEN_W * SCREEN_H];
		if (!SimpleCanvas.create(pbuf, "Hello", SCREEN_W, SCREEN_H))
			return;
		for (int i = 0; i < SCREEN_W * SCREEN_H; i++)
			pbuf[i] = 0xffffffff;
		drawString("こんにちわ、世界\nHello,World", 12, 48);
	}
	
	public static void main(String[] args) {
		Main main = new Main();
		main.repaint();
	}
}

実行例

出た。

gcj.gif

コメント

コメントはありません。 コメント/gcj/23?

お名前:

MENU

now: 5

リンク


最新の20件
2018-10-07 2018-09-20 2018-09-03 2018-05-09 2017-09-29 2017-01-10 2016-12-11 2016-10-04 2016-08-14 2016-05-29 2015-12-28 2013-02-25 2013-02-21 2013-02-20 2013-02-12 2013-02-11 2013-02-10
最新の20件
2010-02-01 2010-01-31 2010-01-30 2010-01-29 2010-01-16

Counter: 3446, today: 1, yesterday: 1

添付ファイル: filegcj.gif 820件 [詳細]

リロード   新規 編集 凍結 差分 添付 複製 改名   トップ 一覧 検索 最終更新 バックアップ   ヘルプ   最終更新のRSS

Last-modified: 2008-03-28 (金) 15:48:00 (3859d);  Modified by mona
PukiWiki 1.4.6 Copyright © 2001-2005 PukiWiki Developers Team. License is GPL.
Based on "PukiWiki" 1.3 by yu-ji
Powered by PHP 5.2.17
HTML convert time to 0.041 sec.