For example, given this encoding:
\u0412\u044b\u0431\u043e\u0440\u043a\u0430
I expect to see:
Выборка
(If your reader program is working, that should be some Cyrillic
characters, the first looking like an ASCII B).
And that is the case everywhere in Tcl (yeah!). But not the RBC
toolkit (axis labels in stripcharts, as an example), which instead
prints:
Ð.Ñ.боÑ.ка
(Should see a few D-type characters, and a few degree symbols - which
is not what is really wanted).
As a bit of history, BLT with Tcl 8.4 prints this string correctly.
So there is a regression here. I suspect that it is Tcl that has
changed/improved, and RBC has not been updated. But I am only
guessing. Tcl 8.5 is generally handling this unicode text very well.
Tcl 8.4 was near to unusable in this aspect. That is why I am fiddling
with RBC - it works with Tcl 8.5. I guess there is still no news on
BLT. Seems such a pity to loose a great toolkit. But it seems that is
what is happening. Sigh.
Anyone else using RBC with Tcl 8.5.x, and using unicode text? Any
ideas on possible workarounds?
TIA for any pointers.
--
Roger Oberholtzer
I have never used RBC, but perhaps Plotchart could be an alternative
for the
charting facilities? It is pure Tcl/Tk and I just tried your title -
showed
up in Cyrillic all right.
Regards,
Arjen
Thanks. I have looked at this as a BLT replacement. But I did not get
the feeling it performed very well in my use. The various BLT charts
are excellent when you are plotting ever changing data. I define a
vector in C, and then update the vector in C to update the plot. I
have many plots being updated each more than once second. BLT is
really well done in this sense (and many other). I know what I want
for Christmas (BLT in Tcl 8.5.7 and newer)!!
Recently I stumbled upon this web page:
http://pdqi.com/w/pw/pdqi/Wize/Blt
It has a BLT version that should be usable with Tcl8.5. I haven't
tried it yet.
Rüdiger
Right, that is something Plotchart does not really handle ;). It would
require a C-part where you can trace the contents of a C variable.
I have recently worked on some performance improvements - where the
problem
was that you needed to draw tens or hundreds of thousands of data.
The
associated drawing method is quite fast now, but I have not released
it
yet.
Regards,
Arjen
>
> Recently I stumbled upon this web page:http://pdqi.com/w/pw/pdqi/Wize/Blt
>
> It has a BLT version that should be usable with Tcl8.5. I haven't
> tried it yet.
I recall looking at this in the past. IIRC, it was a complete release
with Tcl/Tk as well. I seem to recall that it was only with an early
release of 8.5, which I think Blt worked with after a few minor edits.
There is a specific release of Tcl where Blt is no longer usable. I
think WIZE uses the Tcl version just before this. I will of course
check again. I would love to be surprised.
So obviously no one is using Tcl 8.5.7 and Blt. All apps using BLT are
stuck in an older Tcl release. No one has found a better compromise?
I will investigate how RBC is doing the text encoding. Maybe I will
get lucky and it is fixable by me. I will keep the list posted.
We just switched to RBC and it works very well so far, including with
scaled fonts. The code is very much the same as BLT (refactored, you
know) so I would think that deficiencies in RBC are directly from BLT.
We don't use unicode, as I'm sure you can guess, but I'd really
encourage you to contribute to RBC. I'm pretty sure our BLT days are over.
--Tim
I was in the same need, so I decided to check the sources to see
what's happening. The toolkit is using plain XDrawString(), so is
unaware of any encoding issues and render the string "as is".
When I tried to switch to use Tk_DrawChars(), which is aware of
unicode strings, I get some X protocol errors when the code tries
to rotate the font (y axis title, for example).
I'm still investigating the issue.
After some fiddling with the code I end up with a patch to, at
least, make horizontal text unicode aware, while non-horizontal
text still uses XDrawString().
The patch also makes the code compile with Tk 8.6
(removed some deprecated use of interp->result).
Note that you almost certainly will have the same issue with
postscript output (as I had).
Try to apply the patch and rebuild rbc with
$ CFLAGS="-DHAVE_UTF" ./configure
Hope this helps.
Emiliano
Patch follows:
Index: generic/rbcPs.c
===================================================================
--- generic/rbcPs.c (revisión: 48)
+++ generic/rbcPs.c (copia de trabajo)
@@ -1654,6 +1654,8 @@
Tcl_UniChar ch;
#endif
int limit;
+ char buf[50];
+ int bufcount;
limit = PSTOKEN_BUFSIZ - 4; /* High water mark for the scratch
* buffer. */
@@ -1665,8 +1667,11 @@
Rbc_AppendToPostScript(tokenPtr, "(", (char *)NULL);
count = 0;
dst = tokenPtr->scratchArr;
- src = fragPtr->text;
- end = fragPtr->text + fragPtr->count;
+ Tcl_UtfToExternal(NULL, NULL, fragPtr->text, fragPtr->count,
+ 0, NULL, buf, 49, NULL, &bufcount, NULL);
+ src = buf;
+ end = buf + bufcount;
+
while (src < end) {
if (count > limit) {
/* Don't let the scatch buffer overflow */
Index: generic/rbcVecMath.c
===================================================================
--- generic/rbcVecMath.c (revisión: 48)
+++ generic/rbcVecMath.c (copia de trabajo)
@@ -1647,20 +1647,20 @@
if ((errno== EDOM) || (value != value)) {
Tcl_AppendResult(interp, "domain error: argument not in valid
range",
(char *) NULL);
- Tcl_SetErrorCode(interp, "ARITH", "DOMAIN", interp->result,
+ Tcl_SetErrorCode(interp, "ARITH", "DOMAIN",
Tcl_GetStringResult(interp),
(char *) NULL);
} else if ((errno== ERANGE) || IS_INF(value)) {
if (value == 0.0) {
Tcl_AppendResult(interp,
"floating-point value too small to
represent",
(char *) NULL);
- Tcl_SetErrorCode(interp, "ARITH", "UNDERFLOW", interp-
>result,
+ Tcl_SetErrorCode(interp, "ARITH", "UNDERFLOW",
Tcl_GetStringResult(interp),
(char *) NULL);
} else {
Tcl_AppendResult(interp,
"floating-point value too large to
represent",
(char *) NULL);
- Tcl_SetErrorCode(interp, "ARITH", "OVERFLOW", interp-
>result,
+ Tcl_SetErrorCode(interp, "ARITH", "OVERFLOW",
Tcl_GetStringResult(interp),
(char *) NULL);
}
} else {
@@ -1669,7 +1669,7 @@
sprintf(buf, "%d", errno);
Tcl_AppendResult(interp, "unknown floating-point error, ",
"errno = ",
buf, (char *) NULL);
- Tcl_SetErrorCode(interp, "ARITH", "UNKNOWN", interp->result,
+ Tcl_SetErrorCode(interp, "ARITH", "UNKNOWN",
Tcl_GetStringResult(interp),
(char *) NULL);
}
}
Index: generic/rbcText.c
===================================================================
--- generic/rbcText.c (revisión: 48)
+++ generic/rbcText.c (copia de trabajo)
@@ -18,7 +18,7 @@
static Tcl_HashTable bitmapGCTable;
static int initialized;
-static void DrawTextLayout _ANSI_ARGS_((Display *display, Drawable
drawable, GC gc, Tk_Font font, register int x, register int y,
TextLayout *textPtr));
+static void DrawTextLayout _ANSI_ARGS_((Display *display, Drawable
drawable, GC gc, Tk_Font font, register int x, register int y,
TextLayout *textPtr, double theta));
/*
*--------------------------------------------------------------
@@ -36,24 +36,29 @@
*--------------------------------------------------------------
*/
static void
-DrawTextLayout(display, drawable, gc, font, x, y, textPtr)
+DrawTextLayout(display, drawable, gc, font, x, y, textPtr, theta)
Display *display;
Drawable drawable;
GC gc;
Tk_Font font;
register int x, y; /* Origin of text */
TextLayout *textPtr;
+ double theta;
{
register TextFragment *fragPtr;
register int i;
+ char buf[50];
+ int count;
fragPtr = textPtr->fragArr;
for (i = 0; i < textPtr->nFrags; i++, fragPtr++) {
-#if HAVE_UTF
- Tk_DrawChars(display, drawable, gc, font, fragPtr->text,
fragPtr->count, x + fragPtr->x, y + fragPtr->y);
-#else
- XDrawString(display, drawable, gc, x + fragPtr->x, y +
fragPtr->y, fragPtr->text, fragPtr->count);
-#endif /*HAVE_UTF*/
+ if (theta == 0.0) {
+ Tk_DrawChars(display, drawable, gc, font, fragPtr->text,
fragPtr->count, x + fragPtr->x, y + fragPtr->y);
+ } else {
+ Tcl_UtfToExternal(NULL, NULL, fragPtr->text, fragPtr-
>count,
+ 0, NULL, buf, 49, NULL, &count, NULL);
+ XDrawString(display, drawable, gc, x + fragPtr->x, y +
fragPtr->y, buf, count);
+ }
}
}
@@ -554,7 +559,7 @@
XSetFont(display, gc, Tk_FontId(tsPtr->font));
XSetForeground(display, gc, 1);
- DrawTextLayout(display, bitmap, gc, tsPtr->font, 0, 0, textPtr);
+ DrawTextLayout(display, bitmap, gc, tsPtr->font, 0, 0, textPtr,
tsPtr->theta);
#ifdef WIN32
/*
@@ -760,12 +765,12 @@
XSetForeground(display, tsPtr->gc, color1->pixel);
}
DrawTextLayout(display, drawable, tsPtr->gc, tsPtr->font,
x + 1,
- y + 1, textPtr);
+ y + 1, textPtr, tsPtr->theta);
if (color2 != NULL) {
XSetForeground(display, tsPtr->gc, color2->pixel);
}
DrawTextLayout(display, drawable, tsPtr->gc, tsPtr->font,
x, y,
- textPtr);
+ textPtr, tsPtr->theta);
/* Reset the foreground color back to its original
setting,
* so not to invalidate the GC cache. */
@@ -776,14 +781,15 @@
if ((tsPtr->shadow.offset > 0) && (tsPtr->shadow.color !=
NULL)) {
XSetForeground(display, tsPtr->gc, tsPtr->shadow.color-
>pixel);
DrawTextLayout(display, drawable, tsPtr->gc, tsPtr->font,
- x + tsPtr->shadow.offset, y + tsPtr-
>shadow.offset, textPtr);
+ x + tsPtr->shadow.offset, y + tsPtr->shadow.offset,
+ textPtr, tsPtr->theta);
XSetForeground(display, tsPtr->gc, tsPtr->color->pixel);
}
if (active) {
XSetForeground(display, tsPtr->gc, tsPtr->activeColor-
>pixel);
}
DrawTextLayout(display, drawable, tsPtr->gc, tsPtr->font, x,
y,
- textPtr);
+ textPtr, tsPtr->theta);
if (active) {
XSetForeground(display, tsPtr->gc, tsPtr->color->pixel);
}
Index: generic/rbcVector.c
===================================================================
--- generic/rbcVector.c (revisión: 48)
+++ generic/rbcVector.c (copia de trabajo)
@@ -9,7 +9,6 @@
* See "license.terms" for details.
*/
-#include <tclInt.h>
#include <string.h>
#include "rbcVector.h"
> I was in the same need, so I decided to check the sources to see
> what's happening. The toolkit is using plain XDrawString(), so is
> unaware of any encoding issues and render the string "as is".
> When I tried to switch to use Tk_DrawChars(), which is aware of
> unicode strings, I get some X protocol errors when the code tries
> to rotate the font (y axis title, for example).
> I'm still investigating the issue.
>
> After some fiddling with the code I end up with a patch to, at
> least, make horizontal text unicode aware, while non-horizontal
> text still uses XDrawString().
> The patch also makes the code compile with Tk 8.6
> (removed some deprecated use of interp->result).
>
> Note that you almost certainly will have the same issue with
> postscript output (as I had).
>
> Try to apply the patch and rebuild rbc with
> $ CFLAGS="-DHAVE_UTF" ./configure
>
> Hope this helps.
> Emiliano
>
> Patch follows:
I will try this when I am back in the office. I will also look at the
rotated font stuff to see if I can help.
Thanks!
--
Roger Oberholtzer
Your patch did indeed sort out the non-rotated text. Thanks!
I see that the 'theta' value indicates that the text is to be rotated.
In my case, the value is 90.0 for text on the vertical axis. As you
noted, this text is not correct. I guess that the code to deal with
this is in the case where theta is not 0.0, Unfortunately, I know
nothing about text handling in Tk via C. But I can surely learn. I
guess there is code in the canvas that deals with rotating text.
Perhaps that is the place to start looking. I tried the sample Tcl
code in http://wiki.tcl.tk/4599, and I got the letter E written in
various sizes - but not rotated (Linux openSUSE 11.2). Perhaps it is
how the font is requested:
-adobe-times-medium-r-*-*-[rotmatrix $size $angle]-*-*-*-*-*-*-*.
Would this be how this is done in Tcls of 8.5.7 or newer vintage?
After all, font handling seems vastly improved.
Any and all pointers are welcome.
BTW, are you going to provide the patches to the RBC project on
sourceforge?
Already done. See
https://sourceforge.net/tracker/?func=detail&atid=1127644&aid=3131754&group_id=262358.
If you have Tk HEAD newer than 2010-12-02 and the submitted patch
applied,
you can build rbc with
$ CFLAGS="-DHAVE_ANGLEDTEXT" ./configure
and have full text internationalization / rotation. This feature was
possible thanks to Donal Fellows's work in rotated text (part ot TIP
#119),
who not only wrote the code but also was kind enough to publish the
angled
text interface in the internal stubs table upon my request.
All credit belongs to him.
Regards.
Emiliano
> Already done. See https://sourceforge.net/tracker/?func=detail&atid=1127644&aid=3131754....
>
> If you have Tk HEAD newer than 2010-12-02 and the submitted patch applied,
> you can build rbc with
>
> $ CFLAGS="-DHAVE_ANGLEDTEXT" ./configure
So I cannot use this with 8.5.7? OK. I need to see how openSUSE are
maintaining Tcl/Tk releases. They have something called 'Factory'
which should be the latest release. But I bet this does not have such
a current Tk. And the head as of 2010-12-2 is a minimum requirement?
> and have full text internationalization / rotation. This feature was
> possible thanks to Donal Fellows's work in rotated text (part ot TIP
> #119),
> who not only wrote the code but also was kind enough to publish the
> angled
> text interface in the internal stubs table upon my request.
> All credit belongs to him.
Thanks Donal!
No, 8.5 doesn't implement the required features.
> And the head as of 2010-12-2 is a minimum requirement?
From my limited understanding on how stubs work, I'd say yes.
OTHO, if you are about to build rbc yourself, you can also build
Tcl and Tk HEAD prior to rbc. If you can't for any reason, you're
stuck with the old behaviour.
Regards
Emiliano
Yes. The API required wasn't exported at all from Tk before that.
Donal.
OK. I have started seeing how I can do this in the openSUSE Build
Service. It stays current with the last stable release. I will see
about setting up a repository that stays current with the head
release. For those who don't know it, the Build Service provides
repositories with installable software for many Linux platforms. It
even makes Windows compiles of many things. Tcl/Tk included.