blob: c21d55f741e9f8396617e9ece15b76bc817697a9 [file] [log] [blame]
/*
*******************************************************************************
* Copyright (C) 1996-2000, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/text/Attic/JamoHangulTransliterator.java,v $
* $Date: 2000/06/28 20:49:54 $
* $Revision: 1.8 $
*
*****************************************************************************************
*/
package com.ibm.text;
import java.util.*;
/**
* A transliterator that converts Jamo to Hangul
*
* <p>Copyright &copy; IBM Corporation 1999. All rights reserved.
*
* @author Mark Davis
*/
public class JamoHangulTransliterator extends Transliterator {
private static final String COPYRIGHT =
"\u00A9 IBM Corporation 1999. All rights reserved.";
/**
* Package accessible ID for this transliterator.
*/
static String _ID = "Jamo-Hangul";
/**
* Constructs a transliterator.
*/
public JamoHangulTransliterator() {
super(_ID, null);
setMaximumContextLength(3);
}
/**
* Implements {@link Transliterator#handleTransliterate}.
*/
protected void handleTransliterate(Replaceable text,
Position offsets, boolean incremental) {
/**
* Performs transliteration changing Jamo to Hangul
*/
int cursor = offsets.start;
int limit = offsets.limit;
if (cursor >= limit) return;
int count[] = new int[1];
char last = filteredCharAt(text, cursor++);
while (cursor <= limit) {
char next = 0xFFFF; // go over end of string, just in case
if (cursor < limit) next = filteredCharAt(text, cursor);
char replacement = composeHangul(last, next, count);
if (replacement != last) {
text.replace(cursor-1, cursor-1 + count[0], String.valueOf(replacement));
limit = limit - count[0] + 1; // fix up limit 2 => -1, 1 => 0
last = replacement;
if (next == 0xFFFF) break;
// don't change cursor, so we revisit char
} else {
++cursor;
last = next;
}
}
++limit;
offsets.contextLimit += limit - offsets.limit;
offsets.limit = limit;
offsets.start = cursor;
}
static final int
SBase = 0xAC00, LBase = 0x1100, VBase = 0x1161, TBase = 0x11A7,
LCount = 19, VCount = 21, TCount = 28,
NCount = VCount * TCount, // 588
SCount = LCount * NCount, // 11172
LLimit = 0x1200;
/**
* Return composed character (if it is a modern jamo)
* last otherwise.
* If there is a replacement, returns count[0] = 2 if ch was used, 1 otherwise
*/
public static char composeHangul(char last, char ch, int[] count) {
count[0] = 2; // default is replace 2 chars
// check to see if two current characters are L and V
int LIndex = last - LBase;
if (0 <= LIndex && LIndex < LCount) {
int VIndex = ch - VBase;
if (0 <= VIndex && VIndex < VCount) {
// make syllable of form LV
return (char)(SBase + (LIndex * VCount + VIndex) * TCount);
} else {
// it is isolated, so fix!
count[0] = 1; // not using ch
return (char)(SBase + (LIndex * VCount) * TCount);
}
}
// if neither case was true, see if we have an isolated Jamo we need to fix
if (LBase <= last && last < LLimit) {
// need to fix: it is either medial or final!
int VIndex = last - VBase;
if (0 <= VIndex && VIndex < VCount) {
LIndex = 0x110B - LBase; // use empty consonant
// make syllable of form LV
count[0] = 1; // not using ch
return (char)(SBase + (LIndex * VCount + VIndex) * TCount);
}
// ok, see if final. Use null consonant + a + final
int TIndex = last - TBase;
if (0 <= TIndex && TIndex <= TCount) { // need to fix!
count[0] = 1; // not using ch
return (char)(0xC544 + TIndex);
}
}
// check to see if two current characters are LV and T
int SIndex = last - SBase;
if (0 <= SIndex && SIndex < SCount && (SIndex % TCount) == 0) {
int TIndex = ch - TBase;
if (0 <= TIndex && TIndex <= TCount) {
// make syllable of form LVT
return (char)(last + TIndex);
}
}
return last;
}
}