diff options
Diffstat (limited to 'libXmu/src/Xct.c')
-rw-r--r-- | libXmu/src/Xct.c | 687 |
1 files changed, 687 insertions, 0 deletions
diff --git a/libXmu/src/Xct.c b/libXmu/src/Xct.c new file mode 100644 index 000000000..b186d27d7 --- /dev/null +++ b/libXmu/src/Xct.c @@ -0,0 +1,687 @@ +/* $Xorg: Xct.c,v 1.4 2001/02/09 02:03:53 xorgcvs Exp $ */ + +/* + +Copyright 1989, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* $XFree86: xc/lib/Xmu/Xct.c,v 1.8 2001/07/25 15:04:50 dawes Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/Xfuncs.h> +#include "Xct.h" +#include <stdio.h> + +#define UsedGraphic 0x0001 +#define UsedDirection 0x0002 + +typedef struct _XctPriv { + XctString ptr; + XctString ptrend; + unsigned flags; + XctHDirection *dirstack; + unsigned dirsize; + char **encodings; + unsigned enc_count; + XctString itembuf; + unsigned buf_count; +} *XctPriv; + +#define IsMore(priv) ((priv)->ptr != (priv)->ptrend) +#define AmountLeft(priv) ((priv)->ptrend - (priv)->ptr) + +#include <stdlib.h> + +#define HT 0x09 +#define NL 0x0a +#define ESC 0x1b +#define CSI 0x9b + +#define IsLegalC0(data, c) (((c) == HT) || ((c) == NL) || \ + (((data)->version > XctVersion) && \ + ((data)->flags & XctAcceptC0Extensions))) + +#define IsLegalC1(priv, c) (((data)->version > XctVersion) && \ + ((data)->flags & XctAcceptC1Extensions)) + +#define IsI2(c) (((c) >= 0x20) && ((c) <= 0x2f)) +#define IsI3(c) (((c) >= 0x30) && ((c) <= 0x3f)) +#define IsESCF(c) (((c) >= 0x30) && ((c) <= 0x7e)) +#define IsCSIF(c) (((c) >= 0x40) && ((c) <= 0x7e)) +#define IsC0(c) ((c) <= 0x1f) +#define IsGL(c) (((c) >= 0x20) && ((c) <= 0x7f)) +#define IsC1(c) (((c) >= 0x80) && ((c) <= 0x9f)) +#define IsGR(c) ((c) >= 0xa0) + +#define HasC 1 +#define HasGL 2 +#define HasGR 4 +#define ToGL 8 + +/* + * Prototypes + */ +static void ComputeGLGR(XctData); +static int Handle94GR(XctData, int); +static int Handle96GR(XctData, int); +static int HandleExtended(XctData data, int); +static int HandleGL(XctData, int); +static int HandleMultiGL(XctData, int); +static int HandleMultiGR(XctData data, int); +static void ShiftGRToGL(XctData, int); + +/* + * Implementation + */ +static void +ComputeGLGR(register XctData data) +{ + /* XXX this will need more work if more sets are registered */ + if ((data->GL_set_size == 94) && (data->GL_char_size == 1) && + (data->GL[0] == '\102') && + (data->GR_set_size == 96) && (data->GR_char_size == 1)) + data->GLGR_encoding = data->GR_encoding; + else if ((data->GL_set_size == 94) && (data->GL_char_size == 1) && + (data->GL[0] == '\112') && + (data->GR_set_size == 94) && (data->GR_char_size == 1)) + data->GLGR_encoding = data->GR_encoding; + else + data->GLGR_encoding = (char *)NULL; +} + +static int +HandleGL(register XctData data, int c) +{ + switch (c) { + case 0x42: + data->GL = "\102"; + data->GL_encoding = "ISO8859-1"; + break; + case 0x4a: + data->GL = "\112"; + data->GL_encoding = "JISX0201.1976-0"; + break; + default: + return 0; + } + data->GL_set_size = 94; + data->GL_char_size = 1; + ComputeGLGR(data); + return 1; +} + +static int +HandleMultiGL(register XctData data, int c) +{ + switch (c) { + case 0x41: + data->GL = "\101"; + data->GL_encoding = "GB2312.1980-0"; + break; + case 0x42: + data->GL = "\102"; + data->GL_encoding = "JISX0208.1983-0"; + break; + case 0x43: + data->GL = "\103"; + data->GL_encoding = "KSC5601.1987-0"; + break; + default: + return 0; + } + data->GL_set_size = 94; + data->GL_char_size = 2; +#ifdef notdef + if (c < 0x60) + data->GL_char_size = 2; + else if (c < 0x70) + data->GL_char_size = 3; + else + data->GL_char_size = 4; +#endif + data->GLGR_encoding = (char *)NULL; + return 1; +} + +static int +Handle94GR(register XctData data, int c) +{ + switch (c) { + case 0x49: + data->GR = "\111"; + data->GR_encoding = "JISX0201.1976-0"; + break; + default: + return 0; + } + data->priv->flags &= ~ToGL; + data->GR_set_size = 94; + data->GR_char_size = 1; + data->GLGR_encoding = (char *)NULL; + return 1; +} + +static int +Handle96GR(register XctData data, int c) +{ + switch (c) { + case 0x41: + data->GR = "\101"; + data->GR_encoding = "ISO8859-1"; + break; + case 0x42: + data->GR = "\102"; + data->GR_encoding = "ISO8859-2"; + break; + case 0x43: + data->GR = "\103"; + data->GR_encoding = "ISO8859-3"; + break; + case 0x44: + data->GR = "\104"; + data->GR_encoding = "ISO8859-4"; + break; + case 0x46: + data->GR = "\106"; + data->GR_encoding = "ISO8859-7"; + break; + case 0x47: + data->GR = "\107"; + data->GR_encoding = "ISO8859-6"; + break; + case 0x48: + data->GR = "\110"; + data->GR_encoding = "ISO8859-8"; + break; + case 0x4c: + data->GR = "\114"; + data->GR_encoding = "ISO8859-5"; + break; + case 0x4d: + data->GR = "\115"; + data->GR_encoding = "ISO8859-9"; + break; + default: + return 0; + } + data->priv->flags &= ~ToGL; + data->GR_set_size = 96; + data->GR_char_size = 1; + ComputeGLGR(data); + return 1; +} + +static int +HandleMultiGR(register XctData data, int c) +{ + switch (c) { + case 0x41: + data->GR = "\101"; + if (data->flags & XctShiftMultiGRToGL) + data->GR_encoding = "GB2312.1980-0"; + else + data->GR_encoding = "GB2312.1980-1"; + break; + case 0x42: + data->GR = "\102"; + if (data->flags & XctShiftMultiGRToGL) + data->GR_encoding = "JISX0208.1983-0"; + else + data->GR_encoding = "JISX0208.1983-1"; + break; + case 0x43: + data->GR = "\103"; + if (data->flags & XctShiftMultiGRToGL) + data->GR_encoding = "KSC5601.1987-0"; + else + data->GR_encoding = "KSC5601.1987-1"; + break; + default: + return 0; + } + if (data->flags & XctShiftMultiGRToGL) + data->priv->flags |= ToGL; + else + data->priv->flags &= ~ToGL; + data->GR_set_size = 94; + data->GR_char_size = 2; +#ifdef notdef + if (c < 0x60) + data->GR_char_size = 2; + else if (c < 0x70) + data->GR_char_size = 3; + else + data->GR_char_size = 4; +#endif + data->GLGR_encoding = (char *)NULL; + return 1; +} + +static int +HandleExtended(register XctData data, int c) +{ + register XctPriv priv = data->priv; + XctString enc = data->item + 6; + register XctString ptr = enc; + unsigned i, len; + + while (*ptr != 0x02) { + if (!*ptr || (++ptr == priv->ptr)) + return 0; + } + data->item = ptr + 1; + data->item_length = priv->ptr - data->item; + len = ptr - enc; + for (i = 0; + (i < priv->enc_count) && + strncmp(priv->encodings[i], (char *)enc, len); + i++) + ; + if (i == priv->enc_count) { + XctString cp; + + for (cp = enc; cp != ptr; cp++) { + if ((!IsGL(*cp) && !IsGR(*cp)) || (*cp == 0x2a) || (*cp == 0x3f)) + return 0; + } + ptr = (XctString)malloc((unsigned)len + 1); + (void) memmove((char *)ptr, (char *)enc, len); + ptr[len] = 0x00; + priv->enc_count++; + if (priv->encodings) + priv->encodings = (char **)realloc( + (char *)priv->encodings, + priv->enc_count * sizeof(char *)); + else + priv->encodings = (char **)malloc(sizeof(char *)); + priv->encodings[i] = (char *)ptr; + } + data->encoding = priv->encodings[i]; + data->char_size = c - 0x30; + return 1; +} + +static void +ShiftGRToGL(register XctData data, int hasCdata) +{ + register XctPriv priv = data->priv; + register int i; + + if (data->item_length > priv->buf_count) { + priv->buf_count = data->item_length; + if (priv->itembuf) + priv->itembuf = (XctString)realloc((char *)priv->itembuf, + priv->buf_count); + else + priv->itembuf = (XctString)malloc(priv->buf_count); + } + (void) memmove((char *)priv->itembuf, (char *)data->item, + data->item_length); + data->item = priv->itembuf; + if (hasCdata) { + for (i = data->item_length; --i >= 0; ) { + if (IsGR(data->item[i])) + data->item[i] &= 0x7f; + } + } else { + for (i = data->item_length; --i >= 0; ) + data->item[i] &= 0x7f; + } +} + +/* Create an XctData structure for parsing a Compound Text string. */ +XctData +XctCreate(_Xconst unsigned char *string, int length, XctFlags flags) +{ + register XctData data; + register XctPriv priv; + + data = (XctData)malloc(sizeof(struct _XctRec) + sizeof(struct _XctPriv)); + if (!data) + return data; + data->priv = priv = (XctPriv)(data + 1); + data->total_string = (XctString)string; + data->total_length = length; + data->flags = flags; + priv->dirstack = (XctHDirection *)NULL; + priv->dirsize = 0; + priv->encodings = (char **)NULL; + priv->enc_count = 0; + priv->itembuf = (XctString)NULL; + priv->buf_count = 0; + XctReset(data); + return data; +} + +/* Reset the XctData structure to re-parse the string from the beginning. */ +void +XctReset(register XctData data) +{ + register XctPriv priv = data->priv; + + priv->ptr = data->total_string; + priv->ptrend = data->total_string + data->total_length; + data->item = (XctString)NULL; + data->item_length = 0; + data->encoding = (char *)NULL; + data->char_size = 1; + data->horizontal = XctUnspecified; + data->horz_depth = 0; + priv->flags = 0; + data->GL_set_size = data->GR_set_size = 0; /* XXX */ + (void)HandleGL(data, (unsigned char)0x42); + (void)Handle96GR(data, (unsigned char)0x41); + data->version = 1; + data->can_ignore_exts = 0; + /* parse version, if present */ + if ((data->total_length >= 4) && + (priv->ptr[0] == ESC) && (priv->ptr[1] == 0x23) && + IsI2(priv->ptr[2]) && + ((priv->ptr[3] == 0x30) || (priv->ptr[3] == 0x31))) { + data->version = priv->ptr[2] - 0x1f; + if (priv->ptr[3] == 0x30) + data->can_ignore_exts = 1; + priv->ptr += 4; + } +} + +/* Parse the next "item" from the Compound Text string. The return value + * indicates what kind of item is returned. The item itself, and the current + * contextual state, are reported as components of the XctData structure. + */ +XctResult +XctNextItem(register XctData data) +{ + register XctPriv priv = data->priv; + unsigned char c; + int len, bits; + +#define NEXT data->item_length++; priv->ptr++ + + while (IsMore(priv)) { + data->item = priv->ptr; + data->item_length = 0; + c = *priv->ptr; + if (c == ESC) { + NEXT; + while (IsMore(priv) && IsI2(*priv->ptr)) { + NEXT; + } + if (!IsMore(priv)) + return XctError; + c = *priv->ptr; + NEXT; + if (!IsESCF(c)) + return XctError; + switch (data->item[1]) { + case 0x24: + if (data->item_length > 3) { + if (data->item[2] == 0x28) { + if (HandleMultiGL(data, c)) + continue; + } else if (data->item[2] == 0x29) { + if (HandleMultiGR(data, c)) + continue; + } + } + break; + case 0x25: + if ((data->item_length == 4) && (data->item[2] == 0x2f) && + (c <= 0x3f)) { + if ((AmountLeft(priv) < 2) || + (priv->ptr[0] < 0x80) || (priv->ptr[1] < 0x80)) + return XctError; + len = *priv->ptr - 0x80; + NEXT; + len = (len << 7) + (*priv->ptr - 0x80); + NEXT; + if (AmountLeft(priv) < len) + return XctError; + data->item_length += len; + priv->ptr += len; + if (c <= 0x34) { + if (!HandleExtended(data, c) || + ((data->horz_depth == 0) && + (priv->flags & UsedDirection))) + return XctError; + priv->flags |= UsedGraphic; + return XctExtendedSegment; + } + } + break; + case 0x28: + if (HandleGL(data, c)) + continue; + break; + case 0x29: + if (Handle94GR(data, c)) + continue; + break; + case 0x2d: + if (Handle96GR(data, c)) + continue; + break; + } + } else if (c == CSI) { + NEXT; + while (IsMore(priv) && IsI3(*priv->ptr)) { + NEXT; + } + while (IsMore(priv) && IsI2(*priv->ptr)) { + NEXT; + } + if (!IsMore(priv)) + return XctError; + c = *priv->ptr; + NEXT; + if (!IsCSIF(c)) + return XctError; + if (c == 0x5d) { + if ((data->item_length == 3) && + ((data->item[1] == 0x31) || (data->item[1] == 0x32))) { + data->horz_depth++; + if (priv->dirsize < data->horz_depth) { + priv->dirsize += 10; + if (priv->dirstack) + priv->dirstack = (XctHDirection *) + realloc((char *)priv->dirstack, + priv->dirsize * + sizeof(XctHDirection)); + else + priv->dirstack = (XctHDirection *) + malloc(priv->dirsize * + sizeof(XctHDirection)); + } + priv->dirstack[data->horz_depth - 1] = data->horizontal; + if (data->item[1] == 0x31) + data->horizontal = XctLeftToRight; + else + data->horizontal = XctRightToLeft; + if ((priv->flags & UsedGraphic) && + !(priv->flags & UsedDirection)) + return XctError; + priv->flags |= UsedDirection; + if (data->flags & XctHideDirection) + continue; + return XctHorizontal; + } else if (data->item_length == 2) { + if (!data->horz_depth) + return XctError; + data->horz_depth--; + data->horizontal = priv->dirstack[data->horz_depth]; + if (data->flags & XctHideDirection) + continue; + return XctHorizontal; + } + } + } else if (data->flags & XctSingleSetSegments) { + NEXT; + if IsC0(c) { + data->encoding = (char *)NULL; + data->char_size = 1; + if (IsLegalC0(data, c)) + return XctC0Segment; + } else if (IsGL(c)) { + data->encoding = data->GL_encoding; + data->char_size = data->GL_char_size; + while (IsMore(priv) && IsGL(*priv->ptr)) { + NEXT; + } + if (((data->char_size > 1) && + (data->item_length % data->char_size)) || + ((data->horz_depth == 0) && + (priv->flags & UsedDirection))) + return XctError; + priv->flags |= UsedGraphic; + return XctGLSegment; + } else if (IsC1(c)) { + data->encoding = (char *)NULL; + data->char_size = 1; + if (IsLegalC1(data, c)) + return XctC1Segment; + } else { + data->encoding = data->GR_encoding; + data->char_size = data->GR_char_size; + while (IsMore(priv) && IsGR(*priv->ptr)) { + NEXT; + } + if (((data->char_size > 1) && + (data->item_length % data->char_size)) || + ((data->horz_depth == 0) && + (priv->flags & UsedDirection))) + return XctError; + priv->flags |= UsedGraphic; + if (!(priv->flags & ToGL)) + return XctGRSegment; + ShiftGRToGL(data, 0); + return XctGLSegment; + } + } else { + bits = 0; + while (1) { + if (IsC0(c) || IsC1(c)) { + if ((c == ESC) || (c == CSI)) + break; + if (IsC0(c) ? !IsLegalC0(data, c) : !IsLegalC1(data, c)) + break; + bits |= HasC; + NEXT; + } else { + len = data->item_length; + if (IsGL(c)) { + if ((data->flags & XctShiftMultiGRToGL) && + (bits & HasGR)) + break; + NEXT; + bits |= HasGL; + while (IsMore(priv) && IsGL(*priv->ptr)) { + NEXT; + } + if ((data->GL_char_size > 1) && + ((data->item_length - len) % data->GL_char_size)) + return XctError; + } else { + if ((data->flags & XctShiftMultiGRToGL) && + (bits & HasGL)) + break; + NEXT; + bits |= HasGR; + while (IsMore(priv) && IsGR(*priv->ptr)) { + NEXT; + } + if ((data->GR_char_size > 1) && + ((data->item_length - len) % data->GR_char_size)) + return XctError; + } + } + if (!IsMore(priv)) + break; + c = *priv->ptr; + } + if (data->item_length) { + if (bits & (HasGL|HasGR)) { + priv->flags |= UsedGraphic; + if ((data->horz_depth == 0) && + (priv->flags & UsedDirection)) + return XctError; + if ((data->flags & XctShiftMultiGRToGL) && (bits & HasGR)) + ShiftGRToGL(data, bits & HasC); + } + if ((bits == (HasGL|HasGR)) || + (data->GLGR_encoding && !(bits & HasC))) { + data->encoding = data->GLGR_encoding; + if (data->GL_char_size == data->GR_char_size) + data->char_size = data->GL_char_size; + else + data->char_size = 0; + } else if (bits == HasGL) { + data->encoding = data->GL_encoding; + data->char_size = data->GL_char_size; + } else if (bits == HasGR) { + data->encoding = data->GR_encoding; + data->char_size = data->GR_char_size; + } else { + data->encoding = (char *)NULL; + data->char_size = 1; + if ((bits & HasGL) && + (data->GL_char_size != data->char_size)) + data->char_size = 0; + if ((bits & HasGR) && + (data->GR_char_size != data->char_size)) + data->char_size = 0; + } + return XctSegment; + } + NEXT; + } + if (data->version <= XctVersion) + return XctError; + if (data->flags & XctProvideExtensions) + return XctExtension; + if (!data->can_ignore_exts) + return XctError; + } + return XctEndOfText; +} + +/* Free all data associated with an XctDataStructure. */ +void +XctFree(register XctData data) +{ + unsigned i; + register XctPriv priv = data->priv; + + if (priv->dirstack) + free((char *)priv->dirstack); + if (data->flags & XctFreeString) + free((char *)data->total_string); + for (i = 0; i < priv->enc_count; i++) + free(priv->encodings[i]); + if (priv->encodings) + free((char *)priv->encodings); + if (priv->itembuf) + free((char *)priv->itembuf); + free((char *)data); +} |