2013-02-27 12 views
6

Piszę aplikację terminalową (konsolową), która powinna owijać dowolny tekst w Unicode.określają, czy znak Unicode jest pełnowartościowy czy o połowie szerokości w C++

Terminale zazwyczaj używają czcionki o stałej szerokości (stałej szerokości), więc aby zawinąć tekst, jest to tylko więcej niż zliczanie znaków i obserwowanie, czy słowo pasuje do linii, czy też nie, i stosownie do tego.

Problem polega na tym, że w tabeli Unicode występują znaki o pełnej szerokości, które zajmują szerokość 2 znaków w terminalu.

Zliczanie tych znaków spowoduje wyświetlenie 1 znaku Unicode, ale drukowany znak ma 2 znaki "normalne" (połowa szerokości), łamiąc procedurę owijania, ponieważ nie jest świadomy znaków, które zajmują dwa razy większą szerokość.

Jako przykład, jest to pełnej szerokości znaków (U + 3004, symbol JIS)

 
〄 
12 

To nie zajmuje całą szerokość 2 znaki tutaj chociaż jest sformatowane, ale nie używać dwa razy szerokość zachodniej postaci w terminalu.

Aby sobie z tym poradzić, muszę rozróżnić znaki o pełnej lub połówkowej szerokości, ale nie mogę znaleźć sposobu, aby to zrobić w C++. Czy naprawdę trzeba znać wszystkie znaki o pełnej szerokości w tabeli unicode, aby obejść problem?

+1

Ważne http://www.icu-project.org/apiref/icu4c/uchar_8h.html#a3376f0d34bb23c54671859f1978b4226 i http://www.unicode.org/reports/tr11/ –

+0

Dla których OS/platformy? –

+0

Przepraszam, że to przegapiłem. System operacyjny to Linux. – Noice

Odpowiedz

6

Powinieneś użyć ICU u_getIntPropertyValue z właściwością UCHAR_EAST_ASIAN_WIDTH.

Na przykład:

bool is_fullwidth(UChar32 c) { 
    int width = u_getIntPropertyValue(c, UCHAR_EAST_ASIAN_WIDTH); 
    return width == U_EA_FULLWIDTH || width == U_EA_WIDE; 
} 

Zauważ, że jeśli biblioteka graficzna obsługuje łączenie znaków wtedy będziesz musiał brać pod uwagę również przy określaniu jak wiele komórek sekwencja zastosowań; na przykład: e, a następnie U+0301 POŁĄCZENIE OSTREJ ACCENT zajmie tylko 1 komórkę.

+0

Mam zamiar zastąpić wszystkie połączenia do ICU teraz, aby zminimalizować zależności. Może uda mi się zbudować tabelę wszystkich pełnowartościowych znaków za pomocą metody u_getIntPropertyValue. Dzięki za wskazówkę dla łączących się postaci. Sprawdzę, czy to dotyczy również terminali. – Noice

+0

@Noice Może to nie być już istotne dla Ciebie, ale ostatnio zestawiłem zakresy znaków dla podobnego pytania, tutaj: http://stackoverflow.com/a/15651264/777186 – jogojapan

Powiązane problemy