3 Copyright 1989, 1998 The Open Group
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 Except as contained in this notice, the name of The Open Group shall not be
22 used in advertising or otherwise to promote the sale, use or other dealings
23 in this Software without prior written authorization from The Open Group.
30 #include <X11/Xfuncs.h>
34 #define UsedGraphic 0x0001
35 #define UsedDirection 0x0002
37 typedef struct _XctPriv {
41 XctHDirection *dirstack;
49 #define IsMore(priv) ((priv)->ptr != (priv)->ptrend)
50 #define AmountLeft(priv) ((priv)->ptrend - (priv)->ptr)
59 #define IsLegalC0(data, c) (((c) == HT) || ((c) == NL) || \
60 (((data)->version > XctVersion) && \
61 ((data)->flags & XctAcceptC0Extensions)))
63 #define IsLegalC1(priv, c) (((data)->version > XctVersion) && \
64 ((data)->flags & XctAcceptC1Extensions))
66 #define IsI2(c) (((c) >= 0x20) && ((c) <= 0x2f))
67 #define IsI3(c) (((c) >= 0x30) && ((c) <= 0x3f))
68 #define IsESCF(c) (((c) >= 0x30) && ((c) <= 0x7e))
69 #define IsCSIF(c) (((c) >= 0x40) && ((c) <= 0x7e))
70 #define IsC0(c) ((c) <= 0x1f)
71 #define IsGL(c) (((c) >= 0x20) && ((c) <= 0x7f))
72 #define IsC1(c) (((c) >= 0x80) && ((c) <= 0x9f))
73 #define IsGR(c) ((c) >= 0xa0)
83 static void ComputeGLGR(XctData);
84 static int Handle94GR(XctData, int);
85 static int Handle96GR(XctData, int);
86 static int HandleExtended(XctData data, int);
87 static int HandleGL(XctData, int);
88 static int HandleMultiGL(XctData, int);
89 static int HandleMultiGR(XctData data, int);
90 static void ShiftGRToGL(XctData, int);
96 ComputeGLGR(register XctData data)
98 /* XXX this will need more work if more sets are registered */
99 if ((data->GL_set_size == 94) && (data->GL_char_size == 1) &&
100 (data->GL[0] == '\102') &&
101 (data->GR_set_size == 96) && (data->GR_char_size == 1))
102 data->GLGR_encoding = data->GR_encoding;
103 else if ((data->GL_set_size == 94) && (data->GL_char_size == 1) &&
104 (data->GL[0] == '\112') &&
105 (data->GR_set_size == 94) && (data->GR_char_size == 1))
106 data->GLGR_encoding = data->GR_encoding;
108 data->GLGR_encoding = (char *)NULL;
112 HandleGL(register XctData data, int c)
117 data->GL_encoding = "ISO8859-1";
121 data->GL_encoding = "JISX0201.1976-0";
126 data->GL_set_size = 94;
127 data->GL_char_size = 1;
133 HandleMultiGL(register XctData data, int c)
138 data->GL_encoding = "GB2312.1980-0";
142 data->GL_encoding = "JISX0208.1983-0";
146 data->GL_encoding = "KSC5601.1987-0";
151 data->GL_set_size = 94;
152 data->GL_char_size = 2;
155 data->GL_char_size = 2;
157 data->GL_char_size = 3;
159 data->GL_char_size = 4;
161 data->GLGR_encoding = (char *)NULL;
166 Handle94GR(register XctData data, int c)
171 data->GR_encoding = "JISX0201.1976-0";
176 data->priv->flags &= ~ToGL;
177 data->GR_set_size = 94;
178 data->GR_char_size = 1;
179 data->GLGR_encoding = (char *)NULL;
184 Handle96GR(register XctData data, int c)
189 data->GR_encoding = "ISO8859-1";
193 data->GR_encoding = "ISO8859-2";
197 data->GR_encoding = "ISO8859-3";
201 data->GR_encoding = "ISO8859-4";
205 data->GR_encoding = "ISO8859-7";
209 data->GR_encoding = "ISO8859-6";
213 data->GR_encoding = "ISO8859-8";
217 data->GR_encoding = "ISO8859-5";
221 data->GR_encoding = "ISO8859-9";
226 data->priv->flags &= ~ToGL;
227 data->GR_set_size = 96;
228 data->GR_char_size = 1;
234 HandleMultiGR(register XctData data, int c)
239 if (data->flags & XctShiftMultiGRToGL)
240 data->GR_encoding = "GB2312.1980-0";
242 data->GR_encoding = "GB2312.1980-1";
246 if (data->flags & XctShiftMultiGRToGL)
247 data->GR_encoding = "JISX0208.1983-0";
249 data->GR_encoding = "JISX0208.1983-1";
253 if (data->flags & XctShiftMultiGRToGL)
254 data->GR_encoding = "KSC5601.1987-0";
256 data->GR_encoding = "KSC5601.1987-1";
261 if (data->flags & XctShiftMultiGRToGL)
262 data->priv->flags |= ToGL;
264 data->priv->flags &= ~ToGL;
265 data->GR_set_size = 94;
266 data->GR_char_size = 2;
269 data->GR_char_size = 2;
271 data->GR_char_size = 3;
273 data->GR_char_size = 4;
275 data->GLGR_encoding = (char *)NULL;
280 HandleExtended(register XctData data, int c)
282 register XctPriv priv = data->priv;
283 XctString enc = data->item + 6;
284 register XctString ptr = enc;
287 while (*ptr != 0x02) {
288 if (!*ptr || (++ptr == priv->ptr))
291 data->item = ptr + 1;
292 data->item_length = priv->ptr - data->item;
295 (i < priv->enc_count) &&
296 strncmp(priv->encodings[i], (char *)enc, len);
299 if (i == priv->enc_count) {
302 for (cp = enc; cp != ptr; cp++) {
303 if ((!IsGL(*cp) && !IsGR(*cp)) || (*cp == 0x2a) || (*cp == 0x3f))
306 ptr = (XctString)malloc((unsigned)len + 1);
307 (void) memmove((char *)ptr, (char *)enc, len);
311 priv->encodings = (char **)realloc(
312 (char *)priv->encodings,
313 priv->enc_count * sizeof(char *));
315 priv->encodings = (char **)malloc(sizeof(char *));
316 priv->encodings[i] = (char *)ptr;
318 data->encoding = priv->encodings[i];
319 data->char_size = c - 0x30;
324 ShiftGRToGL(register XctData data, int hasCdata)
326 register XctPriv priv = data->priv;
329 if (data->item_length > priv->buf_count) {
330 priv->buf_count = data->item_length;
332 priv->itembuf = (XctString)realloc((char *)priv->itembuf,
335 priv->itembuf = (XctString)malloc(priv->buf_count);
337 (void) memmove((char *)priv->itembuf, (char *)data->item,
339 data->item = priv->itembuf;
341 for (i = data->item_length; --i >= 0; ) {
342 if (IsGR(data->item[i]))
343 data->item[i] &= 0x7f;
346 for (i = data->item_length; --i >= 0; )
347 data->item[i] &= 0x7f;
351 /* Create an XctData structure for parsing a Compound Text string. */
353 XctCreate(_Xconst unsigned char *string, int length, XctFlags flags)
355 register XctData data;
356 register XctPriv priv;
358 data = (XctData)malloc(sizeof(struct _XctRec) + sizeof(struct _XctPriv));
361 data->priv = priv = (XctPriv)(data + 1);
362 data->total_string = (XctString)string;
363 data->total_length = length;
365 priv->dirstack = (XctHDirection *)NULL;
367 priv->encodings = (char **)NULL;
369 priv->itembuf = (XctString)NULL;
375 /* Reset the XctData structure to re-parse the string from the beginning. */
377 XctReset(register XctData data)
379 register XctPriv priv = data->priv;
381 priv->ptr = data->total_string;
382 priv->ptrend = data->total_string + data->total_length;
383 data->item = (XctString)NULL;
384 data->item_length = 0;
385 data->encoding = (char *)NULL;
387 data->horizontal = XctUnspecified;
388 data->horz_depth = 0;
390 data->GL_set_size = data->GR_set_size = 0; /* XXX */
391 (void)HandleGL(data, (unsigned char)0x42);
392 (void)Handle96GR(data, (unsigned char)0x41);
394 data->can_ignore_exts = 0;
395 /* parse version, if present */
396 if ((data->total_length >= 4) &&
397 (priv->ptr[0] == ESC) && (priv->ptr[1] == 0x23) &&
398 IsI2(priv->ptr[2]) &&
399 ((priv->ptr[3] == 0x30) || (priv->ptr[3] == 0x31))) {
400 data->version = priv->ptr[2] - 0x1f;
401 if (priv->ptr[3] == 0x30)
402 data->can_ignore_exts = 1;
407 /* Parse the next "item" from the Compound Text string. The return value
408 * indicates what kind of item is returned. The item itself, and the current
409 * contextual state, are reported as components of the XctData structure.
412 XctNextItem(register XctData data)
414 register XctPriv priv = data->priv;
418 #define NEXT data->item_length++; priv->ptr++
420 while (IsMore(priv)) {
421 data->item = priv->ptr;
422 data->item_length = 0;
426 while (IsMore(priv) && IsI2(*priv->ptr)) {
435 switch (data->item[1]) {
437 if (data->item_length > 3) {
438 if (data->item[2] == 0x28) {
439 if (HandleMultiGL(data, c))
441 } else if (data->item[2] == 0x29) {
442 if (HandleMultiGR(data, c))
448 if ((data->item_length == 4) && (data->item[2] == 0x2f) &&
450 if ((AmountLeft(priv) < 2) ||
451 (priv->ptr[0] < 0x80) || (priv->ptr[1] < 0x80))
453 len = *priv->ptr - 0x80;
455 len = (len << 7) + (*priv->ptr - 0x80);
457 if (AmountLeft(priv) < len)
459 data->item_length += len;
462 if (!HandleExtended(data, c) ||
463 ((data->horz_depth == 0) &&
464 (priv->flags & UsedDirection)))
466 priv->flags |= UsedGraphic;
467 return XctExtendedSegment;
472 if (HandleGL(data, c))
476 if (Handle94GR(data, c))
480 if (Handle96GR(data, c))
484 } else if (c == CSI) {
486 while (IsMore(priv) && IsI3(*priv->ptr)) {
489 while (IsMore(priv) && IsI2(*priv->ptr)) {
499 if ((data->item_length == 3) &&
500 ((data->item[1] == 0x31) || (data->item[1] == 0x32))) {
502 if (priv->dirsize < data->horz_depth) {
505 priv->dirstack = (XctHDirection *)
506 realloc((char *)priv->dirstack,
508 sizeof(XctHDirection));
510 priv->dirstack = (XctHDirection *)
511 malloc(priv->dirsize *
512 sizeof(XctHDirection));
514 priv->dirstack[data->horz_depth - 1] = data->horizontal;
515 if (data->item[1] == 0x31)
516 data->horizontal = XctLeftToRight;
518 data->horizontal = XctRightToLeft;
519 if ((priv->flags & UsedGraphic) &&
520 !(priv->flags & UsedDirection))
522 priv->flags |= UsedDirection;
523 if (data->flags & XctHideDirection)
525 return XctHorizontal;
526 } else if (data->item_length == 2) {
527 if (!data->horz_depth)
530 data->horizontal = priv->dirstack[data->horz_depth];
531 if (data->flags & XctHideDirection)
533 return XctHorizontal;
536 } else if (data->flags & XctSingleSetSegments) {
539 data->encoding = (char *)NULL;
541 if (IsLegalC0(data, c))
543 } else if (IsGL(c)) {
544 data->encoding = data->GL_encoding;
545 data->char_size = data->GL_char_size;
546 while (IsMore(priv) && IsGL(*priv->ptr)) {
549 if (((data->char_size > 1) &&
550 (data->item_length % data->char_size)) ||
551 ((data->horz_depth == 0) &&
552 (priv->flags & UsedDirection)))
554 priv->flags |= UsedGraphic;
556 } else if (IsC1(c)) {
557 data->encoding = (char *)NULL;
559 if (IsLegalC1(data, c))
562 data->encoding = data->GR_encoding;
563 data->char_size = data->GR_char_size;
564 while (IsMore(priv) && IsGR(*priv->ptr)) {
567 if (((data->char_size > 1) &&
568 (data->item_length % data->char_size)) ||
569 ((data->horz_depth == 0) &&
570 (priv->flags & UsedDirection)))
572 priv->flags |= UsedGraphic;
573 if (!(priv->flags & ToGL))
575 ShiftGRToGL(data, 0);
581 if (IsC0(c) || IsC1(c)) {
582 if ((c == ESC) || (c == CSI))
584 if (IsC0(c) ? !IsLegalC0(data, c) : !IsLegalC1(data, c))
589 len = data->item_length;
591 if ((data->flags & XctShiftMultiGRToGL) &&
596 while (IsMore(priv) && IsGL(*priv->ptr)) {
599 if ((data->GL_char_size > 1) &&
600 ((data->item_length - len) % data->GL_char_size))
603 if ((data->flags & XctShiftMultiGRToGL) &&
608 while (IsMore(priv) && IsGR(*priv->ptr)) {
611 if ((data->GR_char_size > 1) &&
612 ((data->item_length - len) % data->GR_char_size))
620 if (data->item_length) {
621 if (bits & (HasGL|HasGR)) {
622 priv->flags |= UsedGraphic;
623 if ((data->horz_depth == 0) &&
624 (priv->flags & UsedDirection))
626 if ((data->flags & XctShiftMultiGRToGL) && (bits & HasGR))
627 ShiftGRToGL(data, bits & HasC);
629 if ((bits == (HasGL|HasGR)) ||
630 (data->GLGR_encoding && !(bits & HasC))) {
631 data->encoding = data->GLGR_encoding;
632 if (data->GL_char_size == data->GR_char_size)
633 data->char_size = data->GL_char_size;
636 } else if (bits == HasGL) {
637 data->encoding = data->GL_encoding;
638 data->char_size = data->GL_char_size;
639 } else if (bits == HasGR) {
640 data->encoding = data->GR_encoding;
641 data->char_size = data->GR_char_size;
643 data->encoding = (char *)NULL;
645 if ((bits & HasGL) &&
646 (data->GL_char_size != data->char_size))
648 if ((bits & HasGR) &&
649 (data->GR_char_size != data->char_size))
656 if (data->version <= XctVersion)
658 if (data->flags & XctProvideExtensions)
660 if (!data->can_ignore_exts)
666 /* Free all data associated with an XctDataStructure. */
668 XctFree(register XctData data)
671 register XctPriv priv = data->priv;
674 free((char *)priv->dirstack);
675 if (data->flags & XctFreeString)
676 free((char *)data->total_string);
677 for (i = 0; i < priv->enc_count; i++)
678 free(priv->encodings[i]);
680 free((char *)priv->encodings);
682 free((char *)priv->itembuf);