備忘録 JAVA

iTextで禁則処理

iTextで禁則処理を行おうとし、色々調べてみたが、なかなか情報がありませんでした。

なので、こちらこちらを参考に禁則処理を行うことにしました。

禁則処理文字列は禁則処理…文字コード一覧を基準にして作りました。

isSplitCharacterは文字列を1文字ずつ読み取り、その文字は折り返し可能かどうかの判断をしています。
(true…折り返し可能  false…折り返し不可)

今回、FontSelectorを使っていたので、単純にisSplitCharacterのオーバーライドはできませんでした。

なので、FontSelectorを継承したクラスを作成し、そのクラスにisSplitCharacterをオーバーライドしました。

iText1.3と2.1.7だと微妙にsetter getterの名前が変わっているのでバージョンによってコメントアウトをする必要があります。(25~28行目あたり)

[java]

import com.lowagie.text.Font;
import com.lowagie.text.pdf.BaseFont;
import com.lowagie.text.pdf.FontSelector;
import com.lowagie.text.pdf.PdfChunk;
import com.lowagie.text.*;

import java.util.ArrayList;
public class FontSelectorHyphenation extends FontSelector{
public FontSelectorHyphenation ()
{
fonts = new ArrayList();
}

public void addFont(Font font)
{
if(font.getBaseFont() != null)
{
fonts.add(font);
return;
} else
{
BaseFont basefont = font.getCalculatedBaseFont(true);
//itext1.3
// Font font1 = new Font(basefont, font.size(), font.getCalculatedStyle(), font.color());
//itext2.1.7
Font font1 = new Font(basefont, font.getSize(), font.getCalculatedStyle(), font.getColor());
fonts.add(font1);
return;
}
}

public Paragraph Hyphenationparagraph(String s)
{
int i = fonts.size();
if(i == 0)
throw new IndexOutOfBoundsException("No font is defined.");
char ac[] = s.toCharArray();
int j = ac.length;
StringBuffer stringbuffer = new StringBuffer();
Object obj = null;
int k = -1;
// Phrase phrase = new Phrase();
Paragraph paragraph = new Paragraph();
label0:
for(int l = 0; l < j; l++)
{
char c = ac[l];
if(c == '\n' || c == '\r')
{
stringbuffer.append(c);
continue;
}
int i1 = 0;
do
{
if(i1 >= i)
continue label0;
Font font = (Font)fonts.get(i1);
if(font.getBaseFont().charExists(c))
{
if(k == i1)
{
stringbuffer.append(c);
continue label0;
}
if(stringbuffer.length() > 0 && k != -1)
{
Chunk chunk1 = new Chunk(stringbuffer.toString(), (Font)fonts.get(k));
SplitCharacter splitcharacter = setSplitCharacter();
chunk1.setSplitCharacter(splitcharacter);
paragraph.add(chunk1);
stringbuffer = new StringBuffer();
}
stringbuffer.append(c);
k = i1;
continue label0;
}
i1++;
} while(true);
}

if(stringbuffer.length() > 0)
{
Chunk chunk = new Chunk(stringbuffer.toString(), (Font)fonts.get(k));

SplitCharacter splitcharacter = setSplitCharacter();
chunk.setSplitCharacter(splitcharacter);
//phase.add(chunk);
paragraph.add(chunk);
}
return paragraph;

}

private SplitCharacter setSplitCharacter() {
return new SplitCharacter() {
@Override
public boolean isSplitCharacter(int start, int current, int end, char[] cc, PdfChunk[] ck) {
//初期設定
char c;
if (ck == null)
c = cc[current];
else
c = (char) ck[Math.min(current, ck.length - 1)].getUnicodeEquivalent(cc[current]);

char c2;
if (ck == null)
c2 = cc[current];
else
if(ck[Math.min(current+1, ck.length - 1)] != null){
if(current+1 < end){
c2 = (char) ck[Math.min(current+1, ck.length - 1)].getUnicodeEquivalent(cc[current+1]);
}else{
c2 = ' ';
}
}else{
c2 = (char) ck[Math.min(current, ck.length - 1)].getUnicodeEquivalent(cc[current]);
}
char c3;
if (ck == null)
c3 = cc[current];
else
if(ck[Math.min(current+2, ck.length - 1)] != null){
if(current+2 < end){
c3 = (char) ck[Math.min(current+2, ck.length - 1)].getUnicodeEquivalent(cc[current+2]);
}else{
c3 = ' ';
}
}else{
c3 = (char) ck[Math.min(current, ck.length - 1)].getUnicodeEquivalent(cc[current]);
}

char c11;
if (ck == null)
c11 = cc[current];
else{
int current_t = 0;
if(current -1 < 0){
current_t = current;
}else{
current_t = current - 1;
}
if(ck[Math.min(current_t, ck.length - 1)] != null){
c11 = (char) ck[Math.min(current_t, ck.length - 1)].getUnicodeEquivalent(cc[current_t]);
}else{
c11 = (char) ck[Math.min(current, ck.length - 1)].getUnicodeEquivalent(cc[current]);
}
}

//trueの場合は改行する。
//falseの場合は改行しない。

//一つ前の文字が英数字の場合の処理
if(c11 >= 0x20 && c11 <= 0x7e){//!から~まで
if (c <= ' ' || c == '-') {
return true;
}

// if (c < 0x2e80)
return false;
}

if(c != c2 && c2 != c3){
//行頭文字
switch(c){
//終わり括弧類
case 0x002C://,
return false;
case 0xFF0c://,
return false;
case 0x0029://)
return false;
case 0xFF09://)
return false;
case 0x005D://]
return false;
case 0xFF3D://]
return false;
case 0xFF5D://}
return false;
case 0x3001://、
return false;
case 0x3015://〕
return false;
case 0x3009://〉
return false;
case 0x300B://》
return false;
case 0x300D://」
return false;
case 0x300F://』
return false;
case 0x3011://】
return false;
case 0x3019://〙
return false;
case 0x3017://〗
return false;
case 0x301F://〟
return false;
case 0x2019://'
return false;
case 0x201D://"
return false;
case 0xFF60://⦆
return false;
case 0x00BB://»
return false;

//行頭禁則和字
case 0x30FD://ヽ
return false;
case 0x30FE://ヾ
return false;
case 0x30FC://ー
return false;
case 0x30A1://ァ
return false;
case 0x30A3://ィ
return false;
case 0x30A5://ゥ
return false;
case 0x30A7://ェ
return false;
case 0x30A9://ォ
return false;
case 0x30C3://ッ
return false;
case 0x30E3://ャ
return false;
case 0x30E5://ュ
return false;
case 0x30E7://ョ
return false;
case 0x30EE://ヮ
return false;
case 0x30F5://ヵ
return false;
case 0x30F6://ヶ
return false;
case 0x3041://ぁ
return false;
case 0x3043://ぃ
return false;
case 0x3045://ぅ
return false;
case 0x3047://ぇ
return false;
case 0x3049://ぉ
return false;
case 0x3063://っ
return false;
case 0x3083://ゃ
return false;
case 0x3085://ゅ
return false;
case 0x3087://ょ
return false;
case 0x308E://ゎ
return false;
case 0x3095://ゕ
return false;
case 0x3096://ゖ
return false;
case 0x31F0://ㇰ
return false;
case 0x31F1://ㇱ
return false;
case 0x31F2://ㇲ
return false;
case 0x31F3://ㇳ
return false;
case 0x31F4://ㇴ
return false;
case 0x31F5://ㇵ
return false;
case 0x31F6://ㇶ
return false;
case 0x31F7://ㇷ
return false;
case 0x31F8://ㇸ
return false;
case 0x31F9://ㇹ
return false;
case 0x31FA://ㇺ
return false;
case 0x31FB://ㇻ
return false;
case 0x31FC://ㇼ
return false;
case 0x31FD://ㇽ
return false;
case 0x31FE://ㇾ
return false;
case 0x31FF://ㇿ
return false;
case 0x3005://々
return false;
case 0x303B://〻
return false;

//ハイフン類
case 0x2010://‐
return false;
case 0x002D://-
return false;
case 0x30A0://゠
return false;
case 0x003D://=
return false;
case 0xFF1D://=
return false;
case 0x2013://–
return false;
case 0x301C://〜
return false;
case 0xFF5E://~
return false;

//区切り約物
case 0x003F://?
return false;
case 0xFF1F://?
return false;
case 0x0021://!
return false;
case 0xFF01://!
return false;
case 0x203C://‼
return false;
case 0x2047://⁇
return false;
case 0x2048://⁈
return false;
case 0x2049://⁉
return false;

//中点類
case 0x30FB://・
return false;
case 0x003A://:
return false;
case 0xFF1A://:
return false;
case 0x003B://;
return false;
case 0xFF1B://;
return false;

//句点類
case 0x3002://。
return false;
case 0x002E://.
return false;
case 0xFF0E://.
return false;
}

switch(c2){
//終わり括弧類
case 0x002C://,
return false;
case 0xFF0c://,
return false;
case 0x0029://)
return false;
case 0xFF09://)
return false;
case 0x005D://]
return false;
case 0xFF3D://]
return false;
case 0xFF5D://}
return false;
case 0x3001://、
return false;
case 0x3015://〕
return false;
case 0x3009://〉
return false;
case 0x300B://》
return false;
case 0x300D://」
return false;
case 0x300F://』
return false;
case 0x3011://】
return false;
case 0x3019://〙
return false;
case 0x3017://〗
return false;
case 0x301F://〟
return false;
case 0x2019://'
return false;
case 0x201D://"
return false;
case 0xFF60://⦆
return false;
case 0x00BB://»
return false;

//行頭禁則和字
case 0x30FD://ヽ
return false;
case 0x30FE://ヾ
return false;
case 0x30FC://ー
return false;
case 0x30A1://ァ
return false;
case 0x30A3://ィ
return false;
case 0x30A5://ゥ
return false;
case 0x30A7://ェ
return false;
case 0x30A9://ォ
return false;
case 0x30C3://ッ
return false;
case 0x30E3://ャ
return false;
case 0x30E5://ュ
return false;
case 0x30E7://ョ
return false;
case 0x30EE://ヮ
return false;
case 0x30F5://ヵ
return false;
case 0x30F6://ヶ
return false;
case 0x3041://ぁ
return false;
case 0x3043://ぃ
return false;
case 0x3045://ぅ
return false;
case 0x3047://ぇ
return false;
case 0x3049://ぉ
return false;
case 0x3063://っ
return false;
case 0x3083://ゃ
return false;
case 0x3085://ゅ
return false;
case 0x3087://ょ
return false;
case 0x308E://ゎ
return false;
case 0x3095://ゕ
return false;
case 0x3096://ゖ
return false;
case 0x31F0://ㇰ
return false;
case 0x31F1://ㇱ
return false;
case 0x31F2://ㇲ
return false;
case 0x31F3://ㇳ
return false;
case 0x31F4://ㇴ
return false;
case 0x31F5://ㇵ
return false;
case 0x31F6://ㇶ
return false;
case 0x31F7://ㇷ
return false;
case 0x31F8://ㇸ
return false;
case 0x31F9://ㇹ
return false;
case 0x31FA://ㇺ
return false;
case 0x31FB://ㇻ
return false;
case 0x31FC://ㇼ
return false;
case 0x31FD://ㇽ
return false;
case 0x31FE://ㇾ
return false;
case 0x31FF://ㇿ
return false;
case 0x3005://々
return false;
case 0x303B://〻
return false;

//ハイフン類
case 0x2010://‐
return false;
case 0x002D://-
return false;
case 0x30A0://゠
return false;
case 0x003D://=
return false;
case 0xFF1D://=
return false;
case 0x2013://–
return false;
case 0x301C://〜
return false;
case 0xFF5E://~
return false;

//区切り約物
case 0x003F://?
return false;
case 0xFF1F://?
return false;
case 0x0021://!
return false;
case 0xFF01://!
return false;
case 0x203C://‼
return false;
case 0x2047://⁇
return false;
case 0x2048://⁈
return false;
case 0x2049://⁉
return false;

//中点類
case 0x30FB://・
return false;
case 0x003A://:
return false;
case 0xFF1A://:
return false;
case 0x003B://;
return false;
case 0xFF1B://;
return false;

//句点類
case 0x3002://。
return false;
case 0x002E://.
return false;
case 0xFF0E://.
return false;
}
}

//行末禁則文字
switch(c){
case 0x0028://(
return false;
case 0xFF08://(
return false;
case 0xFF3B://[
return false;
case 0x005B://[
return false;
case 0xFF5B://{
return false;
case 0x3014://〔
return false;
case 0x3008://〈
return false;
case 0x300A://《
return false;
case 0x300C://「
return false;
case 0x300E://『
return false;
case 0x3010://【
return false;
case 0x3018://〘
return false;
case 0x3016://〖
return false;
case 0x301D://〝
return false;
case 0x2018://'
return false;
case 0x201C://"
return false;
case 0xFF5F://⦅
return false;
case 0x00AB://«

}
switch(c11){
case 0x0028://(
return false;
case 0xFF08://(
return false;
case 0xFF3B://[
return false;
case 0x005B://[
return false;
case 0xFF5B://{
return false;
case 0x3014://〔
return false;
case 0x3008://〈
return false;
case 0x300A://《
return false;
case 0x300C://「
return false;
case 0x300E://『
return false;
case 0x3010://【
return false;
case 0x3018://〘
return false;
case 0x3016://〖
return false;
case 0x301D://〝
return false;
case 0x2018://'
return false;
case 0x201C://"
return false;
case 0xFF5F://⦅
return false;
case 0x00AB://«

}

//分離禁則
if(c==c2){
switch(c){
case 0x2014://—
return false;
case 0x2026://…
return false;
case 0x2025://‥
return false;
case 0x3033://〳
return false;
case 0x3034://〴
return false;
case 0x3035://〵
return false;
}

}
if(c==c11){
switch(c11){
case 0x2014://—
return false;
case 0x2026://…
return false;
case 0x2025://‥
return false;
case 0x3033://〳
return false;
case 0x3034://〴
return false;
case 0x3035://〵
return false;
}

}
if(c2==c3){
switch(c2){
case 0x2014://—
return false;
case 0x2026://…
return false;
case 0x2025://‥
return false;
case 0x3033://〳
return false;
case 0x3034://〴
return false;
case 0x3035://〵
return false;
}

}

// return ((c >= 0x2e80 && c < 0xd7a0)
// || (c >= 0xf900 && c < 0xfb00)
// || (c >= 0xfe30 && c < 0xfe50)
// || (c >= 0xff61 && c < 0xffa0));
return true;
// return false; //折り返しさせないように、falseを返す
}

};
}

protected ArrayList fonts;

}
[/java]

paragraph関数をHyphenationparagraphに変更すれば使えると思います。

【、あ、あ、あ、あ】等になると微妙に折り返し処理がおかしくなるが、ほぼ思った通りの動作になったからよしとるすかな……

-備忘録, JAVA
-, , , ,

© 2020 かえでBlog