xeij/TextCopy.java
//========================================================================================
// TextCopy.java
// en:Text screen copy
// ja:テキスト画面コピー
// Copyright (C) 2003-2024 Makoto Kamada
//
// This file is part of the XEiJ (X68000 Emulator in Java).
// You can use, modify and redistribute the XEiJ if the conditions are met.
// Read the XEiJ License for more details.
// https://stdkmd.net/xeij/
//========================================================================================
package xeij;
import java.awt.event.*;
import javax.swing.*;
//class TextCopy
// テキスト画面コピー
public class TextCopy {
public static final int TXC_AREA_DISPLAY = 0; //表示範囲
public static final int TXC_AREA_C_WIDTH = 1; //C_WIDTH
public static final int TXC_AREA_VRAM = 2; //VRAM全体
public static final int TXC_AREA_ENCLOSED = 3; //最後に囲んだ範囲
public static int txcAreaMode; //範囲モード
public static boolean txcEncloseEachTime; //true=マウスで都度囲む
//class HanPat
// 半角パターン
static class HanPat {
int c; //文字コード
int p0, p1, p2, p3; //フォントパターン
HanPat next; //同じハッシュコードを持つ次のフォントパターン
}
//class ZenPat
// 全角パターン
static class ZenPat {
int c; //文字コード
int p0, p1, p2, p3, p4, p5, p6, p7; //パターン
ZenPat next; //同じハッシュコードを持つ次のパターン
}
static HanPat[] hanTable; //半角ハッシュテーブル
static ZenPat[] zenTable; //全角ハッシュテーブル
static int pressedX, pressedY; //マウスの左ボタンが押された位置の画面座標。-1=なし
static int enclosedX1, enclosedY1, enclosedX2, enclosedY2; //最後に囲んだ範囲
public static int txcRow1, txcRow2, txcCol1, txcCol2; //現在選択されている範囲。-1=なし
//txcInit ()
// 初期化
public static void txcInit () {
String v = Settings.sgsGetString ("textcopyarea").toLowerCase ();
txcAreaMode = (v.equals ("display") ? TXC_AREA_DISPLAY :
v.equals ("c_width") ? TXC_AREA_C_WIDTH :
v.equals ("vram") ? TXC_AREA_VRAM :
v.equals ("enclosed") ? TXC_AREA_ENCLOSED :
TXC_AREA_DISPLAY);
txcEncloseEachTime = Settings.sgsGetOnOff ("textcopy");
pressedX = -1;
pressedY = -1;
enclosedX1 = 0;
enclosedY1 = 0;
enclosedX2 = 0;
enclosedY2 = 0;
txcRow1 = -1;
txcRow2 = -1;
txcCol1 = -1;
txcCol2 = -1;
} //txcInit
//txcTini ()
// 後始末
public static void txcTini () {
Settings.sgsPutString ("textcopyarea",
txcAreaMode == TXC_AREA_DISPLAY ? "display" :
txcAreaMode == TXC_AREA_C_WIDTH ? "c_width" :
txcAreaMode == TXC_AREA_VRAM ? "vram" :
txcAreaMode == TXC_AREA_ENCLOSED ? "enclosed" :
"display");
Settings.sgsPutOnOff ("textcopy", txcEncloseEachTime);
} //txcTini
//txcMakeMenuItem ()
// テキスト画面コピーメニューアイテムを作る
public static JMenuItem txcMakeMenuItem () {
return ComponentFactory.setEnabled (
Multilingual.mlnText (
ComponentFactory.createMenuItem (
"Text screen copy", 'C', XEiJ.MNB_MODIFIERS,
new ActionListener () {
@Override public void actionPerformed (ActionEvent ae) {
txcCopy ();
}
}),
"ja", "テキスト画面コピー"),
XEiJ.clpClipboard != null);
} //txcMakeMenuItem
//txcMakeSettingMenu ()
// テキスト画面コピー設定メニューを作る
public static JMenu txcMakeSettingMenu () {
ActionListener listener = new ActionListener () {
@Override public void actionPerformed (ActionEvent ae) {
Object source = ae.getSource ();
String command = ae.getActionCommand ();
switch (command) {
case "Display area": //表示領域
txcAreaMode = TXC_AREA_DISPLAY;
break;
case "C_WIDTH":
txcAreaMode = TXC_AREA_C_WIDTH;
break;
case "Entire VRAM": //VRAM全体
txcAreaMode = TXC_AREA_VRAM;
break;
case "Last enclosed area": //最後に囲んだ範囲
txcAreaMode = TXC_AREA_ENCLOSED;
break;
case "Enclose each time with mouse": //マウスで都度囲む
txcEncloseEachTime = ((JCheckBoxMenuItem) source).isSelected ();
break;
}
}
};
ButtonGroup areaGroup = new ButtonGroup ();
return ComponentFactory.setEnabled (
Multilingual.mlnText (
ComponentFactory.createMenu (
"Text screen copy setting",
Multilingual.mlnText (
ComponentFactory.createRadioButtonMenuItem (areaGroup, txcAreaMode == TXC_AREA_DISPLAY, "Display area", listener),
"ja", "表示領域"),
ComponentFactory.createRadioButtonMenuItem (areaGroup, txcAreaMode == TXC_AREA_C_WIDTH, "C_WIDTH", listener),
Multilingual.mlnText (
ComponentFactory.createRadioButtonMenuItem (areaGroup, txcAreaMode == TXC_AREA_VRAM, "Entire VRAM", listener),
"ja", "VRAM 全体"),
Multilingual.mlnText (
ComponentFactory.createRadioButtonMenuItem (areaGroup, txcAreaMode == TXC_AREA_ENCLOSED, "Last enclosed area", listener),
"ja", "最後に囲んだ範囲"),
ComponentFactory.createHorizontalSeparator (),
Multilingual.mlnText (
ComponentFactory.createCheckBoxMenuItem (txcEncloseEachTime, "Enclose each time with mouse", listener),
"ja", "マウスで都度囲む")
),
"ja", "テキスト画面コピー設定"),
XEiJ.clpClipboard != null);
} //txcMakeSettingMenu
//txcReset ()
// リセット
// ハッシュテーブルを破棄する
public static void txcReset () {
hanTable = null;
zenTable = null;
} //txcReset
//txcMousePressed (screenX, screenY)
// マウスの左ボタンが押された
public static void txcMousePressed (int screenX, int screenY) {
if ((VideoController.vcnReg3Curr & (1 << 5)) == 0) { //テキスト画面が表示されていない
return; //何もしない
}
screenX = Math.max (0, Math.min (XEiJ.pnlScreenWidth - 1, screenX));
screenY = Math.max (0, Math.min (XEiJ.pnlScreenHeight - 1, screenY));
pressedX = screenX; //押された位置の画面座標を保存する
pressedY = screenY;
} //txcMousePressed
//txcMouseMoved (screenX, screenY)
// マウスが動いた
public static void txcMouseMoved (int screenX, int screenY) {
if ((VideoController.vcnReg3Curr & (1 << 5)) == 0) { //テキスト画面が表示されていない
return; //何もしない
}
if (pressedX < 0) { //押されていない
return; //何もしない
}
screenX = Math.max (0, Math.min (XEiJ.pnlScreenWidth - 1, screenX));
screenY = Math.max (0, Math.min (XEiJ.pnlScreenHeight - 1, screenY));
calcLocation (screenX, screenY);
if (0 <= txcRow1) { //選択あり
XEiJ.pnlPanel.repaint ();
}
} //txcMouseMoved
//txcMouseReleased (screenX, screenY)
// マウスの左ボタンが離された
public static void txcMouseReleased (int screenX, int screenY) {
if ((VideoController.vcnReg3Curr & (1 << 5)) == 0) { //テキスト画面が表示されていない
return; //何もしない
}
if (pressedX < 0) { //押されていない
return; //何もしない
}
screenX = Math.max (0, Math.min (XEiJ.pnlScreenWidth - 1, screenX));
screenY = Math.max (0, Math.min (XEiJ.pnlScreenHeight - 1, screenY));
calcLocation (screenX, screenY);
if (0 <= txcRow1) { //選択あり
XEiJ.clpCopy (getText (txcRow1, txcRow2, txcCol1, txcCol2)); //テキスト画面から文字列を読み取ってクリップボードにコピーする
}
pressedX = -1;
pressedY = -1;
txcRow1 = -1;
txcRow2 = -1;
txcCol1 = -1;
txcCol2 = -1;
XEiJ.pnlPanel.repaint ();
} //txcMouseReleased
//calcLocation ()
// 選択範囲を求める
static void calcLocation (int screenX, int screenY) {
int x1 = pressedX; //押された位置の画面座標
int y1 = pressedY;
int x2 = screenX; //現在位置の画面座標
int y2 = screenY;
if (x2 < x1) { //x1<=x2にする
int t = x1;
x1 = x2;
x2 = t;
}
if (y2 < y1) { //y1<=y2にする
int t = y1;
y1 = y2;
y2 = t;
}
x1 += CRTC.crtR10TxXCurr; //VRAM座標の開始位置
y1 += CRTC.crtR11TxYCurr;
x2 += CRTC.crtR10TxXCurr; //VRAM座標の終了位置。1024x1024を超える場合がある
y2 += CRTC.crtR11TxYCurr;
int col1 = (x1 + 4) >> 3; //開始桁。桁の右半分にあるときその桁を含まない
int col2 = (x2 - 4) >> 3; //終了桁。桁の左半分にあるときその桁を含まない
int row1 = (y1 + 8) >> 4; //開始行。行の下半分にあるときその行を含まない
int row2 = (y2 - 8) >> 4; //終了行。行の上半分にあるときその行を含まない
if (col1 <= col2 && row1 <= row2) { //1桁以上かつ1行以上
enclosedX1 = x1;
enclosedY1 = y1;
enclosedX2 = x2;
enclosedY2 = y2;
txcCol1 = col1;
txcCol2 = col2;
txcRow1 = row1;
txcRow2 = row2;
} else { //さもなくば
txcCol1 = -1;
txcCol2 = -1;
txcRow1 = -1;
txcRow2 = -1;
}
} //calcLocation
//txcCopy ()
// コピー
public static void txcCopy () {
int x1 = CRTC.crtR10TxXCurr; //左上ドット座標
int y1 = CRTC.crtR11TxYCurr;
int x2, y2; //右下ドット座標
if (txcAreaMode == TXC_AREA_DISPLAY) { //表示範囲
int w = (CRTC.crtR03HDispEndCurr - CRTC.crtR02HBackEndCurr) << 3;
int h = (CRTC.crtR07VDispEndCurr - CRTC.crtR06VBackEndCurr);
if (CRTC.crtDuplication || CRTC.crtDupExceptSp) { //ラスタ2度読み
h >>= 1;
} else if (CRTC.crtInterlace) { //インターレース
h <<= 1;
}
x2 = x1 + w - 1;
y2 = y1 + h - 1;
} else if (txcAreaMode == TXC_AREA_C_WIDTH) { //C_WIDTH
//CONCTRL(16,n)
// 0 768x512 text
// 1 768x512 text+graphic16
// 2 512x512 text
// 3 512x512 text+graphic16
// 4 512x512 text+graphic256
// 5 512x512 text+graphic65536
int v = MainMemory.mmrHumanVersion;
int a = (v == 0x0302 ? 0x6800 + 0xa890 + 0x29b1 :
v == 0x0301 ? 0x6800 + 0xa77a + 0x29b1 :
v == 0x020f ? 0x6800 + 0xa822 + 0x29b1 :
v == 0x0203 ? 0x6800 + 0x96dc + 0x29af :
v == 0x0202 ? 0x6800 + 0x9950 + 0x29af :
v == 0x0201 ? 0x6800 + 0x9910 + 0x29af :
v == 0x0200 ? 0x6800 + 0x9910 + 0x29af :
//!!! 0x0101 0x0100
-1);
if (a < 0) {
return;
}
int n = MC68060.mmuPeekByteZeroData (a, 1);
if (0 <= n && n <= 1) { //768x512
x2 = x1 + 768 - 1;
y2 = y1 + 512 - 1;
} else if (2 <= n && n <= 5) { //512x512
x2 = x1 + 512 - 1;
y2 = y1 + 512 - 1;
} else {
return;
}
} else if (txcAreaMode == TXC_AREA_VRAM) { //VRAM全体
x2 = x1 + 1024 - 1;
y2 = y1 + 1024 - 1;
} else if (txcAreaMode == TXC_AREA_ENCLOSED) { //最後に囲んだ範囲
x1 = enclosedX1; //初回は0,0,0,0なのでNO DATAになる
y1 = enclosedY1;
x2 = enclosedX2;
y2 = enclosedY2;
} else {
return;
}
int col1 = (x1 + 4) >> 3; //開始桁。桁の右半分にあるときその桁を含まない
int col2 = (x2 - 4) >> 3; //終了桁。桁の左半分にあるときその桁を含まない
int row1 = (y1 + 8) >> 4; //開始行。行の下半分にあるときその行を含まない
int row2 = (y2 - 8) >> 4; //終了行。行の上半分にあるときその行を含まない
//テキスト画面から文字列を読み取ってクリップボードにコピーする
XEiJ.clpCopy (getText (row1, row2, col1, col2));
} //txcCopy
//makeHash ()
// ROMフォントからハッシュテーブルを作る
static void makeHash () {
byte[] m = MainMemory.mmrM8;
hanTable = new HanPat[65536];
zenTable = new ZenPat[65536];
//半角
for (int s = 0xff; 0x20 <= s; s--) { //SJISコード
int c = CharacterCode.chrSJISToChar[
s == 0x80 ? 0x5c : //\→¥
s == 0x81 ? 0x7e : //~→ ̄
s == 0x82 ? 0x7c : //¦→|
(0x86 <= s && s <= 0x9f && s != 0x90) || (0xe0 <= s && s <= 0xfd) ? s ^ 0x20 : //ひらがな→カタカナ
s]; //文字コード
if (c == 0) {
continue;
}
for (int n = 2; 0 <= n; n--) { //種類。0=半角,1=上付き1/4角,2=下付き1/4角
int a; //フォントアドレス
int p0, p1, p2, p3; //フォントパターン
int h; //ハッシュコード
if (n == 0) { //半角
a = 0x00f3a800 + (s << 4); //8x16フォントアドレス
} else { //1/4角
a = 0x00f3a000 + (s << 3); //8x8フォントアドレス
}
p0 = ((m[a ] ) << 24 |
(m[a + 1] & 255) << 16 |
(m[a + 2] & 255) << 8 |
(m[a + 3] & 255));
p1 = ((m[a + 4] ) << 24 |
(m[a + 5] & 255) << 16 |
(m[a + 6] & 255) << 8 |
(m[a + 7] & 255));
if (n == 0) { //半角
p2 = ((m[a + 8] ) << 24 |
(m[a + 9] & 255) << 16 |
(m[a + 10] & 255) << 8 |
(m[a + 11] & 255));
p3 = ((m[a + 12] ) << 24 |
(m[a + 13] & 255) << 16 |
(m[a + 14] & 255) << 8 |
(m[a + 15] & 255));
} else if (n == 1) { //上付き1/4角
p2 = 0;
p3 = 0;
} else { //下付き1/4角
p2 = p0;
p3 = p1;
p0 = 0;
p1 = 0;
}
if ((p0 | p1 | p2 | p3) == 0 ||
(p0 & p1 & p2 & p3) == -1) { //空白
continue;
}
for (int u = 3; 0 <= u; u--) { //装飾。0=ノーマル,1=太字,2=反転,3=太字反転
int q0 = p0, q1 = p1, q2 = p2, q3 = p3; //装飾されたフォントパターン
if ((u & 1) != 0) { //太字
q0 |= (q0 >> 1) & 0x7f7f7f7f;
q1 |= (q1 >> 1) & 0x7f7f7f7f;
q2 |= (q2 >> 1) & 0x7f7f7f7f;
q3 |= (q3 >> 1) & 0x7f7f7f7f;
}
if ((u & 2) != 0) { //反転
q0 = ~q0;
q1 = ~q1;
q2 = ~q2;
q3 = ~q3;
}
h = ((q0 * 31 + q1) * 31 + q2) * 31 + q3;
h = ((h >> 16) + h) & 65535; //装飾されたフォントパターンのハッシュコード
HanPat pat = new HanPat ();
pat.c = c; //文字コード
pat.p0 = q0; //装飾されたフォントパターン
pat.p1 = q1;
pat.p2 = q2;
pat.p3 = q3;
pat.next = hanTable[h]; //リストの先頭に挿入する
hanTable[h] = pat;
} //for m
} //for n
} //for s
//全角
for (int row = 77 - 1; 0 <= row; row--) { //行
for (int col = 94 - 1; 0 <= col; col--) { //列
int kum1 = row < 8 ? row : row + 7;
int sh = kum1 >> 1;
int sl = 94 * (kum1 & 1) + col;
sh += 0x81;
sl += 0x40;
if (0xa0 <= sh) {
sh += 0xe0 - 0xa0;
}
if (0x7f <= sl) {
sl += 0x80 - 0x7f;
}
int s = (sh << 8) | sl; //SJISコード
int c = CharacterCode.chrSJISToChar[s]; //文字コード
if (c == 0) {
continue;
}
int a = 0x00f00000 + ((col + 94 * row) << 5); //16x16フォントアドレス
int p0 = ((m[a ] ) << 24 | (m[a + 1] & 255) << 16 |
(m[a + 2] & 255) << 8 | (m[a + 3] & 255));
int p1 = ((m[a + 4] ) << 24 | (m[a + 5] & 255) << 16 |
(m[a + 6] & 255) << 8 | (m[a + 7] & 255));
int p2 = ((m[a + 8] ) << 24 | (m[a + 9] & 255) << 16 |
(m[a + 10] & 255) << 8 | (m[a + 11] & 255));
int p3 = ((m[a + 12] ) << 24 | (m[a + 13] & 255) << 16 |
(m[a + 14] & 255) << 8 | (m[a + 15] & 255));
int p4 = ((m[a + 16] ) << 24 | (m[a + 17] & 255) << 16 |
(m[a + 18] & 255) << 8 | (m[a + 19] & 255));
int p5 = ((m[a + 20] ) << 24 | (m[a + 21] & 255) << 16 |
(m[a + 22] & 255) << 8 | (m[a + 23] & 255));
int p6 = ((m[a + 24] ) << 24 | (m[a + 25] & 255) << 16 |
(m[a + 26] & 255) << 8 | (m[a + 27] & 255));
int p7 = ((m[a + 28] ) << 24 | (m[a + 29] & 255) << 16 |
(m[a + 30] & 255) << 8 | (m[a + 31] & 255));
if ((p0 | p1 | p2 | p3 | p4 | p5 | p6 | p7) == 0 ||
(p0 & p1 & p2 & p3 & p4 & p5 & p6 & p7) == -1) { //空白
continue;
}
for (int u = 3; 0 <= u; u--) { //装飾。0=ノーマル,1=太字,2=反転,3=太字反転
int q0 = p0, q1 = p1, q2 = p2, q3 = p3, q4 = p4, q5 = p5, q6 = p6, q7 = p7; //装飾されたフォントパターン
if ((u & 1) != 0) { //太字
q0 |= (q0 >> 1) & 0x7fff7fff;
q1 |= (q1 >> 1) & 0x7fff7fff;
q2 |= (q2 >> 1) & 0x7fff7fff;
q3 |= (q3 >> 1) & 0x7fff7fff;
q4 |= (q4 >> 1) & 0x7fff7fff;
q5 |= (q5 >> 1) & 0x7fff7fff;
q6 |= (q6 >> 1) & 0x7fff7fff;
q7 |= (q7 >> 1) & 0x7fff7fff;
}
if ((u & 2) != 0) { //反転
q0 = ~q0;
q1 = ~q1;
q2 = ~q2;
q3 = ~q3;
q4 = ~q4;
q5 = ~q5;
q6 = ~q6;
q7 = ~q7;
}
int h = ((((((q0 * 31 + q1) * 31 + q2) * 31 + q3) * 31 + q4) * 31 + q5) * 31 + q6) * 31 + q7;
h = ((h >> 16) + h) & 65535; //装飾されたフォントパターンのハッシュコード
ZenPat pat = new ZenPat ();
pat.c = c; //文字コード
pat.p0 = q0; //装飾されたフォントパターン
pat.p1 = q1;
pat.p2 = q2;
pat.p3 = q3;
pat.p4 = q4;
pat.p5 = q5;
pat.p6 = q6;
pat.p7 = q7;
pat.next = zenTable[h]; //リストの先頭に挿入する
zenTable[h] = pat;
} //for m
} //for col
} //for row
} //makeHash
//getText (row1, row2, col1, col2)
// テキスト画面から文字列を読み取る
// 球面スクロールに対応する。VRAMは128桁64行だが超えていても構わない
public static String getText (int row1, int row2, int col1, int col2) {
int cols = col2 - col1 + 1; //桁数
int rows = row2 - row1 + 1; //行数
if (cols <= 0 && rows <= 0) { //範囲がないとき
return "NO DATA"; //何もせず"NO DATA"を返す
}
int[] co = new int[cols + 1]; //範囲内のVRAMの水平方向のオフセットの配列
for (int c = 0; c < co.length; c++) {
co[c] = (col1 + c) & 127;
}
int[] ra = new int[rows + 15]; //範囲内のVRAMの垂直方向のアドレスの配列
for (int r = 0; r < ra.length; r++) {
ra[r] = 0x00e00000 + (((row1 + r) & 63) << 11);
}
//
if (hanTable == null) {
makeHash ();
}
byte[] m = MainMemory.mmrM8;
StringBuilder sb = new StringBuilder ();
for (int r = 0; r < rows; r++) { //範囲内の行
int a = ra[r];
if (0 < r) {
sb.append ('\n');
}
for (int c = 0; c < cols; c++) { //範囲内の桁
//全角
if (c + 1 < cols) { //右端でない
int a0 = a + co[c];
int a1 = a + co[c + 1];
int p0 = ((m[a0 ] ) << 24 | (m[a1 ] & 255) << 16 |
(m[a0 + ( 1 << 7)] & 255) << 8 | (m[a1 + ( 1 << 7)] & 255));
int p1 = ((m[a0 + ( 2 << 7)] ) << 24 | (m[a1 + ( 2 << 7)] & 255) << 16 |
(m[a0 + ( 3 << 7)] & 255) << 8 | (m[a1 + ( 3 << 7)] & 255));
int p2 = ((m[a0 + ( 4 << 7)] ) << 24 | (m[a1 + ( 4 << 7)] & 255) << 16 |
(m[a0 + ( 5 << 7)] & 255) << 8 | (m[a1 + ( 5 << 7)] & 255));
int p3 = ((m[a0 + ( 6 << 7)] ) << 24 | (m[a1 + ( 6 << 7)] & 255) << 16 |
(m[a0 + ( 7 << 7)] & 255) << 8 | (m[a1 + ( 7 << 7)] & 255));
int p4 = ((m[a0 + ( 8 << 7)] ) << 24 | (m[a1 + ( 8 << 7)] & 255) << 16 |
(m[a0 + ( 9 << 7)] & 255) << 8 | (m[a1 + ( 9 << 7)] & 255));
int p5 = ((m[a0 + (10 << 7)] ) << 24 | (m[a1 + (10 << 7)] & 255) << 16 |
(m[a0 + (11 << 7)] & 255) << 8 | (m[a1 + (11 << 7)] & 255));
int p6 = ((m[a0 + (12 << 7)] ) << 24 | (m[a1 + (12 << 7)] & 255) << 16 |
(m[a0 + (13 << 7)] & 255) << 8 | (m[a1 + (13 << 7)] & 255));
int p7 = ((m[a0 + (14 << 7)] ) << 24 | (m[a1 + (14 << 7)] & 255) << 16 |
(m[a0 + (15 << 7)] & 255) << 8 | (m[a1 + (15 << 7)] & 255));
if ((p0 | p1 | p2 | p3 | p4 | p5 | p6 | p7) == 0 ||
(p0 & p1 & p2 & p3 & p4 & p5 & p6 & p7) == -1) { //空白
a0 += 0x00020000; //ページ1
a1 += 0x00020000;
p0 = ((m[a0 ] ) << 24 | (m[a1 ] & 255) << 16 |
(m[a0 + ( 1 << 7)] & 255) << 8 | (m[a1 + ( 1 << 7)] & 255));
p1 = ((m[a0 + ( 2 << 7)] ) << 24 | (m[a1 + ( 2 << 7)] & 255) << 16 |
(m[a0 + ( 3 << 7)] & 255) << 8 | (m[a1 + ( 3 << 7)] & 255));
p2 = ((m[a0 + ( 4 << 7)] ) << 24 | (m[a1 + ( 4 << 7)] & 255) << 16 |
(m[a0 + ( 5 << 7)] & 255) << 8 | (m[a1 + ( 5 << 7)] & 255));
p3 = ((m[a0 + ( 6 << 7)] ) << 24 | (m[a1 + ( 6 << 7)] & 255) << 16 |
(m[a0 + ( 7 << 7)] & 255) << 8 | (m[a1 + ( 7 << 7)] & 255));
p4 = ((m[a0 + ( 8 << 7)] ) << 24 | (m[a1 + ( 8 << 7)] & 255) << 16 |
(m[a0 + ( 9 << 7)] & 255) << 8 | (m[a1 + ( 9 << 7)] & 255));
p5 = ((m[a0 + (10 << 7)] ) << 24 | (m[a1 + (10 << 7)] & 255) << 16 |
(m[a0 + (11 << 7)] & 255) << 8 | (m[a1 + (11 << 7)] & 255));
p6 = ((m[a0 + (12 << 7)] ) << 24 | (m[a1 + (12 << 7)] & 255) << 16 |
(m[a0 + (13 << 7)] & 255) << 8 | (m[a1 + (13 << 7)] & 255));
p7 = ((m[a0 + (14 << 7)] ) << 24 | (m[a1 + (14 << 7)] & 255) << 16 |
(m[a0 + (15 << 7)] & 255) << 8 | (m[a1 + (15 << 7)] & 255));
if ((p0 | p1 | p2 | p3 | p4 | p5 | p6 | p7) == 0 ||
(p0 & p1 & p2 & p3 & p4 & p5 & p6 & p7) == -1) { //空白
sb.append (" ");
c++;
continue;
}
}
int h = ((((((p0 * 31 + p1) * 31 + p2) * 31 + p3) * 31 + p4) * 31 + p5) * 31 + p6) * 31 + p7;
h = ((h >> 16) + h) & 65535; //ハッシュコード
ZenPat pat = zenTable[h];
while (pat != null) { //リストを辿る
if (pat.p0 == p0 &&
pat.p1 == p1 &&
pat.p2 == p2 &&
pat.p3 == p3 &&
pat.p4 == p4 &&
pat.p5 == p5 &&
pat.p6 == p6 &&
pat.p7 == p7) {
break;
}
pat = pat.next;
}
if (pat != null) { //見つかった
sb.append ((char) pat.c);
c++;
continue;
}
} //if 右端でない
//半角
{
int a0 = a + co[c];
int p0 = ((m[a0 ] ) << 24 |
(m[a0 + ( 1 << 7)] & 255) << 16 |
(m[a0 + ( 2 << 7)] & 255) << 8 |
(m[a0 + ( 3 << 7)] & 255));
int p1 = ((m[a0 + ( 4 << 7)] ) << 24 |
(m[a0 + ( 5 << 7)] & 255) << 16 |
(m[a0 + ( 6 << 7)] & 255) << 8 |
(m[a0 + ( 7 << 7)] & 255));
int p2 = ((m[a0 + ( 8 << 7)] ) << 24 |
(m[a0 + ( 9 << 7)] & 255) << 16 |
(m[a0 + (10 << 7)] & 255) << 8 |
(m[a0 + (11 << 7)] & 255));
int p3 = ((m[a0 + (12 << 7)] ) << 24 |
(m[a0 + (13 << 7)] & 255) << 16 |
(m[a0 + (14 << 7)] & 255) << 8 |
(m[a0 + (15 << 7)] & 255));
if ((p0 | p1 | p2 | p3) == 0 ||
(p0 & p1 & p2 & p3) == -1) { //空白
a0 += 0x00020000; //ページ1
p0 = ((m[a0 ] ) << 24 |
(m[a0 + ( 1 << 7)] & 255) << 16 |
(m[a0 + ( 2 << 7)] & 255) << 8 |
(m[a0 + ( 3 << 7)] & 255));
p1 = ((m[a0 + ( 4 << 7)] ) << 24 |
(m[a0 + ( 5 << 7)] & 255) << 16 |
(m[a0 + ( 6 << 7)] & 255) << 8 |
(m[a0 + ( 7 << 7)] & 255));
p2 = ((m[a0 + ( 8 << 7)] ) << 24 |
(m[a0 + ( 9 << 7)] & 255) << 16 |
(m[a0 + (10 << 7)] & 255) << 8 |
(m[a0 + (11 << 7)] & 255));
p3 = ((m[a0 + (12 << 7)] ) << 24 |
(m[a0 + (13 << 7)] & 255) << 16 |
(m[a0 + (14 << 7)] & 255) << 8 |
(m[a0 + (15 << 7)] & 255));
if ((p0 | p1 | p2 | p3) == 0 ||
(p0 & p1 & p2 & p3) == -1) { //空白
sb.append (' ');
continue;
}
}
int h = ((p0 * 31 + p1) * 31 + p2) * 31 + p3;
h = ((h >> 16) + h) & 65535; //ハッシュコード
HanPat pat = hanTable[h];
while (pat != null) { //リストを辿る
if (pat.p0 == p0 &&
pat.p1 == p1 &&
pat.p2 == p2 &&
pat.p3 == p3) {
break;
}
pat = pat.next;
}
if (pat != null) { //見つかった
sb.append ((char) pat.c);
continue;
}
}
//不明
sb.append ('?');
} //for col
} //for row
return sb.toString ();
} //getText
} //class TextCopy