Hi
this patch adds supoprt for arbitrary unicode values for
plucked characters for antialiased fonts. I tried to keep the
changes to code to be minimal, as well as to preserve backward compatibility,
therefore this patch is centered about using UNICODE tokens
via utf-8, which fits nicely into PalmOS model of multibyte text
(and not using wide strings, as I wanted originally).
In order to work, you need compile plucker with --enable-unicode
and with --disable-imode. For backward compatibility, only UNICODE
tokens are considered, the rest of text comes as before (see the
use of UseLegacyEncoding functions). Since it uses multibyte encoding,
uses8BitChars is set to true regardless of device - btw
why the test in grayfont.c does not use DeviceUses8BitChars()
from os.c, but its own test?
In order to actually see this patch working, you need
my previous patch to parser, and to specify --output-charset=unicode
for plucker-build.
You also need suitable antialiased font, in UCS2 compatible encoding -
e.g. ISO8859_1 is fine, font in Palmos encoding is also fine (with
the exception of a few characters). Of course that would display
only characters from ISO8859_1 range. I have a quick and dirty patch for
palmfontconv to produce fonts with wider range, but that is not
ready for consumption yet. Characters not present in font are displayed
as the last character in font (usually U+00FF LATIN SMALL LETTER Y WITH
DIAERESIS), FindPalmCharForUnicodeChar function is not used anymore
(should be replaced by eventual transliteration/fallback for common
characters)
--
-----------------------------------------------------------
| Radovan Garab�k http://melkor.dnp.fmph.uniba.sk/~garabik/ |
| __..--^^^--..__ garabik @ melkor.dnp.fmph.uniba.sk |
-----------------------------------------------------------
Antivirus alert: file .signature infected by signature virus.
Hi! I'm a signature virus! Copy me into your signature file to help me spread!
diff -urN plucker/configure.in plucker-new/configure.in
--- plucker/configure.in 2003-10-23 21:23:47.000000000 +0200
+++ plucker-new/configure.in 2004-03-03 22:47:19.000000000 +0100
@@ -320,6 +320,7 @@
to get the function names included in POSE's
profiling output ])
AC_ARG_ENABLE(imode, [ --enable-imode to enable i-mode support (also
requires the imodeicons.pdb database)])
+AC_ARG_ENABLE(unicode, [ --enable-unicode to enable unicode support])
AC_ARG_ENABLE(scroll_to_bottom, [ --disable-scroll-to-bottom
always scroll even pages instead of stopping when
the end of the page is reached (will add some extra
diff -urN plucker/viewer/config.h.in plucker-new/viewer/config.h.in
--- plucker/viewer/config.h.in 2004-03-03 13:14:41.000000000 +0100
+++ plucker-new/viewer/config.h.in 2004-03-03 22:42:46.000000000 +0100
@@ -116,3 +116,6 @@
/* Define if supporting word lookup */
#undef SUPPORT_WORD_LOOKUP
+
+/* Define if using unicode mode support */
+#undef UNICODE_MODE
diff -urN plucker/viewer/configure.in plucker-new/viewer/configure.in
--- plucker/viewer/configure.in 2004-03-02 18:56:55.000000000 +0100
+++ plucker-new/viewer/configure.in 2004-03-03 22:56:32.000000000 +0100
@@ -31,6 +31,7 @@
DEFAULT_SKINS=no
DEFAULT_ARMLET=no
DEFAULT_IMODE=no
+DEFAULT_UNICODE=no
DEFAULT_CATEGORY=""
DEFAULT_WAIT_ICON=bubble
DEFAULT_LANG="en de cs it fr ja fo da zh_CN pl ru es tr th ca no"
@@ -418,6 +419,17 @@
AC_DEFINE(HAVE_IMODE,, [ Define if using i-mode support])
fi
+AC_MSG_CHECKING(--enable-unicode argument)
+AC_ARG_ENABLE(unicode, [ --enable-unicode to enable unicode grayfont
support],
+ UNICODE=yes, UNICODE=$DEFAULT_UNICODE)
+AC_MSG_RESULT($UNICODE)
+
+if test "$UNICODE" != "no"; then
+ AC_DEFINE(UNICODE_MODE,, [ Define if using unicode mode support])
+fi
+
+
+
AC_ARG_DISABLE(scroll_to_bottom, [ --disable-scroll-to-bottom
always scroll even pages instead of stopping when
the end of the page is reached (will add some extra
@@ -784,6 +796,11 @@
else
echo " I-mode Support: disabled"
fi
+if test "$UNICODE" != "no" ; then
+ echo " Unicode Support: enabled"
+else
+ echo " Unicode Support: disabled"
+fi
if test "$AXXPAC" != "no" ; then
echo " AxxPac Support: enabled"
else
diff -urN plucker/viewer/const.h plucker-new/viewer/const.h
--- plucker/viewer/const.h 2004-03-02 18:56:55.000000000 +0100
+++ plucker-new/viewer/const.h 2004-03-03 22:49:33.000000000 +0100
@@ -101,3 +101,5 @@
/* 3B 22 is a single character in JIS and Kuten */
#define testDoubleByteJISKuten 0x3B22
+/* 04 00 is a single character in UTF-8 */
+#define testDoubleByteUTF8 0x0400
diff -urN plucker/viewer/grayfont.c plucker-new/viewer/grayfont.c
--- plucker/viewer/grayfont.c 2004-01-09 02:17:10.000000000 +0100
+++ plucker-new/viewer/grayfont.c 2004-03-03 22:25:23.000000000 +0100
@@ -496,6 +496,9 @@
uses8BitChars = ( charEncoding <= charEncodingPalmLatin );
else
uses8BitChars = true;
+#ifdef UNICODE_MODE
+ uses8BitChars = false;
+#endif
err = FtrGet( sysFtrCreator, sysFtrNumWinVersion, &version );
havePalmHiRes = ( HIGH_DENSITY_FEATURE_SET_VERSION <= version );
resource.string[ RESOURCE_NAME_IDLETTER ] = RESOURCE_NAME_ID;
@@ -787,7 +790,7 @@
inOffset = 0;
while ( inOffset < length ) {
WChar ch;
- inOffset += TxtGlueGetNextChar( chars, inOffset, &ch );
+ inOffset += MyTxtGlueGetNextChar( chars, inOffset, &ch );
if ( length < inOffset )
break;
width += GetGlyph( ch )->advance;
@@ -888,6 +891,7 @@
WinDrawOperation oldOperation = winPaint;
Boolean doKern;
+
if ( currentFontPtr == NULL ) {
if ( invert )
WinDrawInvertedChars( chars, length, x, y );
@@ -923,7 +927,7 @@
bitmapTopLeftX = 0;
bitmapTopLeftY = 0;
- TxtGlueGetNextChar( chars, 0, &ch );
+ MyTxtGlueGetNextChar( chars, 0, &ch );
firstKern = GetGlyph( ch )->leftKerning;
switch ( resource.string[ RESOURCE_NAME_ORIENTATION ] )
@@ -1014,7 +1018,7 @@
GrayFontGlyphInfo* glyph;
UInt16 resourceIndex;
- inOffset += TxtGlueGetNextChar( chars, inOffset, &ch );
+ inOffset += MyTxtGlueGetNextChar( chars, inOffset, &ch );
if ( length < inOffset )
break;
glyph = GetGlyph( ch );
@@ -1149,7 +1153,7 @@
WinDrawChar( ch, x, y );
return;
}
- length = TxtGlueSetNextChar( line, 0, ch );
+ length = MyTxtGlueSetNextChar( line, 0, ch );
GrayWinDrawChars( line, length, x, y );
}
diff -urN plucker/viewer/grayfont.h plucker-new/viewer/grayfont.h
--- plucker/viewer/grayfont.h 2004-02-10 03:10:44.000000000 +0100
+++ plucker-new/viewer/grayfont.h 2004-03-03 22:24:47.000000000 +0100
@@ -29,6 +29,7 @@
#include "config.h"
#include "viewer.h"
#include "hires.h"
+#include "unicode.h"
#define GRAY_FONT_LEFT 'L'
#define GRAY_FONT_RIGHT 'R'
diff -urN plucker/viewer/Makefile.in plucker-new/viewer/Makefile.in
--- plucker/viewer/Makefile.in 2004-03-02 18:56:55.000000000 +0100
+++ plucker-new/viewer/Makefile.in 2004-03-03 22:53:40.000000000 +0100
@@ -93,7 +93,7 @@
detailsform.c searchform.c categoryform.c fontform.c \
bookmark.c session.c document.c image.c history.c \
search8.c search.c prefsdata.c anchor.c \
- paragraph.c uncompress.c keyboard.c keyboardform.c \
+ paragraph.c unicode.c uncompress.c keyboard.c keyboardform.c \
list.c link.c renamedocform.c hardcopyform.c font.c \
table.c fullscreenform.c @OS_EXTRA_SRC@
diff -urN plucker/viewer/os.c plucker-new/viewer/os.c
--- plucker/viewer/os.c 2004-01-04 13:02:09.000000000 +0100
+++ plucker-new/viewer/os.c 2004-03-03 21:50:16.000000000 +0100
@@ -38,6 +38,7 @@
#include "image.h"
#include "axxpacimp.h"
#include "skins.h"
+#include "unicode.h"
#include "os.h"
@@ -161,7 +162,7 @@
MemSet( s, MAX_CHARACTER_LENGTH, 0 );
s[ 0 ] = word >> 8;
s[ 1 ] = word & 0xFF;
- return 1 < TxtGlueGetNextChar( s, 0, NULL );
+ return 1 < MyTxtGlueGetNextChar( s, 0, NULL );
}
@@ -432,6 +433,7 @@
#endif
if ( IsDoubleByteSingleChar( testDoubleByteBig5GB2312EUCJPKR ) ||
IsDoubleByteSingleChar( testDoubleByteShiftJIS ) ||
+ IsDoubleByteSingleChar( testDoubleByteUTF8 ) ||
IsDoubleByteSingleChar( testDoubleByteJISKuten ) ) {
uses8BitChars = false;
}
diff -urN plucker/viewer/paragraph.c plucker-new/viewer/paragraph.c
--- plucker/viewer/paragraph.c 2004-02-20 17:19:19.000000000 +0100
+++ plucker-new/viewer/paragraph.c 2004-03-03 23:18:41.000000000 +0100
@@ -340,7 +340,7 @@
static Int16 littleSpace; /* Extra pixels in each */
/* A one-character pushback for character tokens */
-static Char pushedChar = 0;
+static WChar pushedChar = 0;
/* Used to see if the current font is the fixed with font */
static Boolean fixedWidthFont = false;
@@ -396,8 +396,9 @@
tapped position */
while ( offset < len ) {
WChar ch;
-
- offset += TxtGlueGetNextChar( chars, offset, &ch );
+ UseLegacyEncoding(1);
+ offset += MyTxtGlueGetNextChar( chars, offset, &ch );
+ UseLegacyEncoding(0);
charWidth = TxtGlueCharWidth( ch );
if ( CharIsSpace( ch ) ) {
x += charWidth;
@@ -517,7 +518,10 @@
selectedWordBounds[ i ].extent.y )
bottomY = selectedWordBounds[ i ].topLeft.y +
selectedWordBounds[ i ].extent.y;
- stringSize += TxtGlueSetNextChar( selectedWord, stringSize, ch );
+ UseLegacyEncoding(1);
+ stringSize += MyTxtGlueSetNextChar( selectedWord, stringSize, ch );
+ UseLegacyEncoding(0);
+
}
selectedWord[ stringSize ] = '\0';
if ( bounds != NULL ) {
@@ -1555,7 +1559,6 @@
UInt8* functionArgs;
UInt32 charValue;
UInt8 charsToSkip;
- UInt16 palmChar;
#ifdef HAVE_IMODE
DmOpenRef plkrImodeDB;
#endif
@@ -1596,8 +1599,7 @@
}
#endif
- palmChar = FindPalmCharForUnicodeChar( charValue );
- if ( 0 < palmChar && PutNextToken( palmChar ) ) {
+ if ( PutNextToken( charValue ) ) {
pContext->position += charsToSkip;
}
return UNICODE;
@@ -1694,16 +1696,18 @@
Int16 offset;
if ( pushedChar != 0 ) {
- *nextToken = ( UInt8 )pushedChar;
+ UseLegacyEncoding(0); /* the only way for pushedChar to appear is via UNICODE
token */
+ *nextToken = ( WChar )pushedChar;
pushedChar = 0;
return TOKEN_CHARACTER;
}
if ( pContext->last <= pContext->position )
return TOKEN_PARAGRAPH_END;
-
- pContext->position += TxtGlueGetNextChar( pContext->position, 0,
+ UseLegacyEncoding(1);
+ pContext->position += MyTxtGlueGetNextChar( pContext->position, 0,
&nextChar );
+ UseLegacyEncoding(0);
if ( nextChar != '\0' ) {
*nextToken = nextChar;
@@ -1726,11 +1730,11 @@
{
if ( pushedChar != 0 )
return false;
-
+/*
if ( 256 <= nextToken )
return false;
-
- pushedChar = (Char) nextToken;
+*/
+ pushedChar = (WChar) nextToken;
return true;
}
@@ -2287,7 +2291,9 @@
tContext->cursorX += FntCharsWidth( chars, len );
len = 0;
}
- len += TxtGlueSetNextChar( chars, len, nextChar );
+ UseLegacyEncoding(1);
+ len += MyTxtGlueSetNextChar( chars, len, nextChar );
+ UseLegacyEncoding(0);
}
if ( pContext->type == ALIGNMENT_JUSTIFY && nextChar == ' ' ) {
diff -urN plucker/viewer/paragraph.h plucker-new/viewer/paragraph.h
--- plucker/viewer/paragraph.h 2004-02-01 12:26:33.000000000 +0100
+++ plucker-new/viewer/paragraph.h 2004-03-01 23:57:21.000000000 +0100
@@ -26,6 +26,7 @@
#include "viewer.h"
#include "document.h"
#include "util.h"
+#include "unicode.h"
/*
A paragraph as it appears in the input data stream. The height of the
diff -urN plucker/viewer/rotate.c plucker-new/viewer/rotate.c
--- plucker/viewer/rotate.c 2004-01-04 01:21:36.000000000 +0100
+++ plucker-new/viewer/rotate.c 2004-03-03 19:04:23.000000000 +0100
@@ -472,7 +472,7 @@
while ( 0 < length ) {
Boolean missing;
- charWidth = TxtGlueGetNextChar( string, 0, &ch );
+ charWidth = MyTxtGlueGetNextChar( string, 0, &ch );
string += charWidth;
length -= charWidth;
diff -urN plucker/viewer/rotate.h plucker-new/viewer/rotate.h
--- plucker/viewer/rotate.h 2003-08-11 04:31:57.000000000 +0200
+++ plucker-new/viewer/rotate.h 2004-03-03 22:42:14.000000000 +0100
@@ -30,6 +30,7 @@
#include "jogdial.h"
#endif
#include "grayfont.h"
+#include "unicode.h"
#ifdef HAVE_ROTATE
diff -urN plucker/viewer/unicode.c plucker-new/viewer/unicode.c
--- plucker/viewer/unicode.c 1970-01-01 01:00:00.000000000 +0100
+++ plucker-new/viewer/unicode.c 2004-03-03 23:14:14.000000000 +0100
@@ -0,0 +1,128 @@
+#include "unicode.h"
+#include <TxtGlue.h>
+
+#ifdef UNICODE_MODE
+static Boolean usingLegacyEncoding = 1;
+
+void UseLegacyEncoding(Boolean x)
+{
+ usingLegacyEncoding = x;
+}
+
+
+UInt16 Utf8TxtGlueSetNextChar(Char * ioText, UInt32 inOffset, WChar inChar)
+{
+
+ UInt8 count; /* counts how many bytes takes the UTF8 reprezentation
*/
+ UInt8 *pos;
+
+ UInt32 chr;
+
+ pos = (UInt8 *)ioText + inOffset;
+ chr = inChar;
+
+
+ if (chr < 0x80)
+ count = 1;
+ else if (chr < 0x800) {
+ count = 2;
+}
+ else if (chr < 0x10000)
+ count = 3;
+#ifdef UCS4 /* reserved for eventual UCS4 support */
+ else if (chr < 0x110000)
+ count = 4;
+#endif /* UCS4 */
+ else {
+/* invalid character */
+ ioText[inOffset] = (UInt8) '?';
+ return 1;
+ }
+
+ switch (count) { /* note: code falls through cases! */
+#ifdef UCS4
+ case 4:
+ pos[3] = 0x80 | (chr & 0x3f);
+ chr = chr >> 6;
+ chr |= 0x10000;
+#endif /* UCS4 */
+ case 3:
+ pos[2] = 0x80 | (chr & 0x3f);
+ chr = chr >> 6;
+ chr |= 0x800;
+ case 2:
+ pos[1] = 0x80 | (chr & 0x3f);
+ chr = chr >> 6;
+ chr |= 0xc0;
+ case 1:
+ pos[0] = (UInt8) chr;
+ }
+ return count;
+}
+
+
+UInt16 Utf8TxtGlueGetNextChar(const Char * inText,
+ UInt32 inOffset, WChar * outChar)
+{
+
+ UInt8 *s;
+ UInt8 c;
+
+ if (usingLegacyEncoding)
+ return TxtGlueGetNextChar( inText, inOffset, outChar );
+
+ s = (UInt8 *) inText + inOffset; /* source start */
+
+ c = s[0];
+
+
+ if (c<0x80) {
+ if (outChar)
+ *outChar = ((UInt16) c);
+ return 1;
+ }
+
+
+ if (c >= 0xc2) {
+ if (c < 0xe0) {
+ if ((s[1] ^ 0x80) < 0x40) {
+ if (outChar)
+ *outChar = ((UInt16) (c & 0x1f) << 6)
+ | (UInt16) (s[1] ^ 0x80);
+ return 2;
+ }
+ } else if (c < 0xf0) {
+ if ((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
+ && (c >= 0xe1 || s[1] >= 0xa0)) {
+ if (outChar)
+ *outChar = ((UInt16) (c & 0x0f) << 12)
+ | ((UInt16) (s[1] ^ 0x80) << 6)
+ | ((UInt16) (s[2] ^ 0x80));
+ return 3;
+ }
+ }
+#ifdef UCS4
+ else if (c < 0xf8) {
+ if ((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
+ && (s[3] ^ 0x80) < 0x40 && (c >= 0xf1 || s[1] >= 0x90)
+ && (c < 0xf4 || (c == 0xf4 && s[1] < 0x90))
+ ) {
+ if (outChar)
+ *outChar = ((unsigned int) (c & 0x07) << 18)
+ | ((unsigned int) (s[1] ^ 0x80) << 12)
+ | ((unsigned int) (s[2] ^ 0x80) << 6)
+ | (unsigned int) (s[3] ^ 0x80);
+ return 4;
+ }
+ }
+#endif /* UCS4 */
+ }
+ /* invalid multibyte character */
+ if (outChar)
+ *outChar = 0xfffd;
+ return 1;
+
+
+}
+
+#endif /* UNICODE_MODE */
diff -urN plucker/viewer/unicode.h plucker-new/viewer/unicode.h
--- plucker/viewer/unicode.h 1970-01-01 01:00:00.000000000 +0100
+++ plucker-new/viewer/unicode.h 2004-03-03 22:52:34.000000000 +0100
@@ -0,0 +1,31 @@
+#ifndef UNICODE_H
+#define UNICODE_H
+
+#include "config.h"
+#include "viewer.h"
+
+//#define UNICODE_MODE
+//#undef UNICODE_MODE
+
+#ifndef UNICODE_SECTION
+# define UNICODE_SECTION
+#endif
+
+
+#ifdef UNICODE_MODE
+
+UInt16 Utf8TxtGlueSetNextChar( Char* ioText, UInt32 inOffset, WChar inChar )
UNICODE_SECTION;
+#define MyTxtGlueSetNextChar Utf8TxtGlueSetNextChar
+UInt16 Utf8TxtGlueGetNextChar( const Char* inText, UInt32 inOffset, WChar* outChar )
UNICODE_SECTION;
+#define MyTxtGlueGetNextChar Utf8TxtGlueGetNextChar
+void UseLegacyEncoding(Boolean x) UNICODE_SECTION;
+
+
+#else
+#define MyTxtGlueSetNextChar TxtGlueSetNextChar
+#define MyTxtGlueGetNextChar TxtGlueGetNextChar
+#define UseLegacyEncoding(x)
+
+#endif /* UNICODE_MODE */
+
+#endif /* UNICODE_H */