/* * * (c) COPYRIGHT MIT and INRIA, 1996. * Please first read the full copyright statement in file COPYRIGHT. * */ /* * This module has been made using D. Veillard's HTMLstyle.c for Amaya. * * Author: C. Bourgeois * */ /* * Debug mode enabled with STYLE_DEBUG */ /* included headers */ #include "thot_gui.h" #include "thot_sys.h" #include "appaction.h" #include "application.h" #include "attribute.h" #include "document.h" #include "fileaccess.h" #include "genericdriver.h" #include "message.h" #include "pschema.h" #include "presentdriver.h" #include "thotmsg.h" #include "view.h" #include "StyleCss.h" #include "StyleCss_f.h" #include "StyleRules_f.h" #include "StyleParser_f.h" #include "UIcss_f.h" #include "CssMsgTable.h" /* list of CSSInfos */ extern CSSInfoPtr ListCSS[DocumentTableLength]; extern int CssMsgTable; /************************************************************************ * * * PARSING DEFINITIONS * * * ************************************************************************/ /* * This flag is used to switch the parser to a destructive mode where * instead of adding the corresponding style, the rule are deleted. * Manipulate with care !!! */ static boolean HTMLStyleParserDestructiveMode = FALSE; /* * This flag has been added to the original code to know from each parsing * function in the list below whether it has recognised a rule. */ static boolean parsedrule=TRUE; /* * A HTML3StyleValueParser is a function used to parse the * description substring associated to a given style attribute * e.g. : "red" for a color attribute or "12pt bold helvetica" * for a font attribute. */ #ifdef __STDC__ typedef char *(*CSSStyleValueParser) (PresentationTarget target, PresentationContext context, char *attrstr); #else typedef char *(*CSSStyleValueParser) (); #endif /* * Macro's used to generate Parser routines signatures. * These heavily rely on the token-pasting mechanism provided by * the C preprocessor. The string a##b is replaced by the string * "ab", but this is done after the macro is expanded. * This mecanism allows to avoid a lot of typing, errors and keep * the code compact at the price of a loss of readability. * On old fashionned preprocessor (pre-Ansi) the token pasting was * a side effect of the preprocessor implementation on empty * comments. In this case we use a+slash+star+star+slash+b to * produce the same string "ab". */ #if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP) || defined(WWW_MSWINDOWS) #define VALUEPARSER(name) \ static char *ParseCSS##name (PresentationTarget target, \ PresentationContext context, char *attrstr); #else #define VALUEPARSER(name) \ static char *ParseCSS/**/name(); #endif VALUEPARSER(FontFamily) VALUEPARSER(FontStyle) VALUEPARSER(FontVariant) VALUEPARSER(FontWeight) VALUEPARSER(FontSize) VALUEPARSER(Font) VALUEPARSER(Foreground) VALUEPARSER(BackgroundColor) VALUEPARSER(BackgroundImage) VALUEPARSER(BackgroundRepeat) VALUEPARSER(BackgroundAttachment) VALUEPARSER(BackgroundPosition) VALUEPARSER(Background) VALUEPARSER(WordSpacing) VALUEPARSER(LetterSpacing) VALUEPARSER(TextDecoration) VALUEPARSER(VerticalAlign) VALUEPARSER(TextTransform) VALUEPARSER(TextAlign) VALUEPARSER(TextIndent) VALUEPARSER(LineSpacing) VALUEPARSER(MarginTop) VALUEPARSER(MarginRight) VALUEPARSER(MarginBottom) VALUEPARSER(MarginLeft) VALUEPARSER(Margin) VALUEPARSER(PaddingTop) VALUEPARSER(PaddingRight) VALUEPARSER(PaddingBottom) VALUEPARSER(PaddingLeft) VALUEPARSER(Padding) VALUEPARSER(BorderTopWidth) VALUEPARSER(BorderRightWidth) VALUEPARSER(BorderBottomWidth) VALUEPARSER(BorderLeftWidth) VALUEPARSER(BorderWidth) VALUEPARSER(BorderColor) VALUEPARSER(BorderStyle) VALUEPARSER(BorderTop) VALUEPARSER(BorderRight) VALUEPARSER(BorderBottom) VALUEPARSER(BorderLeft) VALUEPARSER(Border) VALUEPARSER(Width) VALUEPARSER(Height) VALUEPARSER(Float) VALUEPARSER(Clear) VALUEPARSER(Display) VALUEPARSER(WhiteSpace) VALUEPARSER(ListStyleType) VALUEPARSER(ListStyleImage) VALUEPARSER(ListStylePosition) VALUEPARSER(ListStyle) /* Sorry, not in CSS but so useful ! */ VALUEPARSER(Test) /* * Description of the set of CSS Style Attributes supported. */ typedef struct CSSStyleAttribute { char *name; CSSStyleValueParser parsing_function; }CSSStyleAttribute; /* * NOTE : Long attribute name MUST be placed before shortened ones ! * e.g. "FONT-SIZE" must be placed before "FONT" */ static CSSStyleAttribute CSSStyleAttributes[] = { {"font-family", ParseCSSFontFamily}, {"font-style", ParseCSSFontStyle}, {"font-variant", ParseCSSFontVariant}, {"font-weight", ParseCSSFontWeight}, {"font-size", ParseCSSFontSize}, {"font", ParseCSSFont}, {"color", ParseCSSForeground}, {"background-color", ParseCSSBackgroundColor}, {"background-image", ParseCSSBackgroundImage}, {"background-repeat", ParseCSSBackgroundRepeat}, {"background-attachment", ParseCSSBackgroundAttachment}, {"background-position", ParseCSSBackgroundPosition}, {"background", ParseCSSBackground}, {"word-spacing", ParseCSSWordSpacing}, {"letter-spacing", ParseCSSLetterSpacing}, {"text-decoration", ParseCSSTextDecoration}, {"vertical-align", ParseCSSVerticalAlign}, {"text-transform", ParseCSSTextTransform}, {"text-align", ParseCSSTextAlign}, {"text-indent", ParseCSSTextIndent}, {"line-height", ParseCSSLineSpacing}, {"margin-top", ParseCSSMarginTop}, {"margin-right", ParseCSSMarginRight}, {"margin-bottom", ParseCSSMarginBottom}, {"margin-left", ParseCSSMarginLeft}, {"margin", ParseCSSMargin}, {"padding-top", ParseCSSPaddingTop}, {"padding-right", ParseCSSPaddingRight}, {"padding-bottom", ParseCSSPaddingBottom}, {"padding-left", ParseCSSPaddingLeft}, {"padding", ParseCSSPadding}, {"border-top-width", ParseCSSBorderTopWidth}, {"border-right-width", ParseCSSBorderRightWidth}, {"border-bottom-width", ParseCSSBorderBottomWidth}, {"border-left-width", ParseCSSBorderLeftWidth}, {"border-width", ParseCSSBorderWidth}, {"border-color", ParseCSSBorderColor}, {"border-style", ParseCSSBorderStyle}, {"border-top", ParseCSSBorderTop}, {"border-right", ParseCSSBorderRight}, {"border-bottom", ParseCSSBorderBottom}, {"border-left", ParseCSSBorderLeft}, {"border", ParseCSSBorder}, {"width", ParseCSSWidth}, {"height", ParseCSSHeight}, {"float", ParseCSSFloat}, {"clear", ParseCSSClear}, {"display", ParseCSSDisplay}, {"white-space", ParseCSSWhiteSpace}, {"list-style-type", ParseCSSListStyleType}, {"list-style-image", ParseCSSListStyleImage}, {"list-style-position", ParseCSSListStylePosition}, {"list-style", ParseCSSListStyle}, /* Extra's wrt. CSS 1.0 */ {"test", ParseCSSTest}, }; #define NB_CSSSTYLEATTRIBUTE (sizeof(CSSStyleAttributes) / \ sizeof(CSSStyleAttributes[0])) /* * A few macro needed to help building the parser */ #define ERR -1000000 #define SKIP_WORD(ptr) { while (isalnum(*ptr)) ptr++; } #define SKIP_PROPERTY(ptr) { while ((*ptr) && (*ptr != ';') && \ (*ptr != '}') && (*ptr != ',')) ptr++; } #define SKIP_INT(ptr) { while (isdigit(*ptr)) ptr++; } #define SKIP_FLOAT(ptr) { while (isdigit(*ptr)) ptr++; \ if (*ptr == '.') do ptr++; while (isdigit(*ptr)); } #define IS_SEPARATOR(ptr) ((*ptr == ',') || (*ptr == ';')) #define IS_BLANK(ptr) (((*(ptr)) == SPACE) || ((*(ptr)) == '\b') || \ ((*(ptr)) == EOL) || ((*(ptr)) == '\r')) #define START_DESCR(ptr) (*ptr == ':') #define IS_WORD(ptr,word) (!strncmp((ptr),(word),strlen(word))) #define IS_CASE_WORD(ptr,word) (!strncasecmp((ptr),(word),strlen(word))) #define IS_NUM(ptr) \ ((isdigit(*ptr)) || (*ptr == '.') || (*ptr == '+') || (*ptr == '-')) #define IS_INT(ptr) (isdigit(*ptr)) #define READ_I(ptr,i) { int l; l = sscanf(ptr,"%d",&i); \ if (l <= 0) i = ERR; else SKIP_INT(ptr); } #define READ_IOF(ptr,i,f) { int d; READ_I(ptr,i); \ if (*ptr == '.') { ptr++; READ_I(ptr,d); f } #ifdef STYLE_DEBUG #define TODO { fprintf(stderr, "code incomplete file %s line %d\n",\ __FILE__,__LINE__); }; #define MSG(msg) fprintf(stderr, msg) #else /*static char *last_message = NULL; */ #define TODO /*#define MSG(msg) last_message = msg */ static char *last_message = NULL; #define MSG(msg) last_message = msg #endif /************************************************************************ * * * PARSER USEFUL FUNCTIONS * * * ************************************************************************/ /*---------------------------------------------------------------------- ParseCssUnit : parse a CSS Unit substring and returns the corresponding value and its unit. ----------------------------------------------------------------------*/ #define UNIT_INVALID 0 #define UNIT_POINT 1 #define UNIT_EM 2 #define UNIT_PIXEL 3 struct unit_def { char *sign; int unit; }; static struct unit_def CssUnitNames[] = { {"pt", DRIVERP_UNIT_PT}, {"pc", DRIVERP_UNIT_PC}, {"in", DRIVERP_UNIT_IN}, {"cm", DRIVERP_UNIT_CM}, {"mm", DRIVERP_UNIT_MM}, {"em", DRIVERP_UNIT_EM}, {"px", DRIVERP_UNIT_PX}, {"ex", DRIVERP_UNIT_XHEIGHT}, {"%", DRIVERP_UNIT_PERCENT}, }; #define NB_UNITS (sizeof(CssUnitNames) / sizeof(struct unit_def)) #ifdef __STDC__ static char *ParseCssUnit (char *attrstr, PresentationValue * pval) #else static char *ParseCssUnit (attrstr, pval) char *attrstr; PresentationValue *pval; #endif { int val = 0; int minus = 0; int real = 0; int valid = 0; int f = 0; int uni; pval->typed_data.unit = DRIVERP_UNIT_REL; SKIP_BLANK (attrstr); if (*attrstr == '-') { minus = 1; attrstr++; SKIP_BLANK (attrstr); } if (*attrstr == '+') { attrstr++; SKIP_BLANK (attrstr); } while ((*attrstr >= '0') && (*attrstr <= '9')) { val *= 10; val += *attrstr - '0'; attrstr++; valid = 1; } if (*attrstr == '.') { real = 1; f = val; val = 0; attrstr++; /* keep only 3 digits */ if ((*attrstr >= '0') && (*attrstr <= '9')) { val = (*attrstr - '0') * 100; attrstr++; if ((*attrstr >= '0') && (*attrstr <= '9')) { val += (*attrstr - '0') * 10; attrstr++; if ((*attrstr >= '0') && (*attrstr <= '9')) { val += *attrstr - '0'; attrstr++; } } while ((*attrstr >= '0') && (*attrstr <= '9')) { attrstr++; } valid = 1; } } if (!valid) { SKIP_WORD (attrstr); pval->typed_data.unit = DRIVERP_UNIT_INVALID; pval->typed_data.value = 0; return (attrstr); } SKIP_BLANK (attrstr); for (uni = 0; uni < NB_UNITS; uni++) { #ifdef WWW_WINDOWS if (!_strnicmp (CssUnitNames[uni].sign, attrstr, strlen (CssUnitNames[uni].sign))) #else /* WWW_WINDOWS */ if (!strncasecmp (CssUnitNames[uni].sign, attrstr, strlen (CssUnitNames[uni].sign))) #endif /* !WWW_WINDOWS */ { pval->typed_data.unit = CssUnitNames[uni].unit; if (real) { DRIVERP_UNIT_SET_FLOAT (pval->typed_data.unit); if (minus) pval->typed_data.value = -(f * 1000 + val); else pval->typed_data.value = f * 1000 + val; } else { if (minus) pval->typed_data.value = -val; else pval->typed_data.value = val; } return (attrstr + strlen (CssUnitNames[uni].sign)); } } /* * not in the list of predefined units. */ pval->typed_data.unit = DRIVERP_UNIT_REL; if (minus) pval->typed_data.value = -val; else pval->typed_data.value = val; return (attrstr); } #ifdef __STDC__ static unsigned int hexa_val (char c) #else static unsigned int hexa_val (c) char c; #endif { if ((c >= '0') && (c <= '9')) return (c - '0'); if ((c >= 'a') && (c <= 'f')) return (c - 'a' + 10); if ((c >= 'A') && (c <= 'F')) return (c - 'A' + 10); return (0); } /************************************************************************ * * * PARSING FUNCTIONS FOR EACH CSS ATTRIBUTE SUPPORTED * * * ************************************************************************ * * * All functions have the same params : * * target : target on which the rule is applied * * context : Presentation context (generic context) used to apply * * the rule * * attrstr : string containing the value to parse. * ************************************************************************/ /*---------------------------------------------------------------------- ParseCSSTest : For testing purposes only !!! ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSTest (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSTest (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { #ifdef STYLE_DEBUG fprintf(stderr, " skipping word, "); #endif SKIP_WORD (attrstr); parsedrule=TRUE; return (attrstr); } /*---------------------------------------------------------------------- ParseCSSBorderTopWidth : parse a CSS BorderTopWidth attribute string. ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSBorderTopWidth (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSBorderTopWidth (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { MSG ("ParseCSSBorderTopWidth "); TODO parsedrule=TRUE; return (attrstr); } /*---------------------------------------------------------------------- ParseCSSBorderRightWidth : parse a CSS BorderRightWidth attribute string. ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSBorderRightWidth (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSBorderRightWidth (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { MSG ("ParseCSSBorderRightWidth "); TODO parsedrule=TRUE; return (attrstr); } /*---------------------------------------------------------------------- ParseCSSBorderBottomWidth : parse a CSS BorderBottomWidth attribute string. ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSBorderBottomWidth (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSBorderBottomWidth (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { MSG ("ParseCSSBorderBottomWidth "); TODO parsedrule=TRUE; return (attrstr); } /*---------------------------------------------------------------------- ParseCSSBorderLeftWidth : parse a CSS BorderLeftWidth attribute string. ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSBorderLeftWidth (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSBorderLeftWidth (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { MSG ("ParseCSSBorderLeftWidth "); TODO return (attrstr); } /*---------------------------------------------------------------------- ParseCSSBorderWidth : parse a CSS BorderWidth attribute string. ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSBorderWidth (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSBorderWidth (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { MSG ("ParseCSSBorderWidth "); TODO parsedrule=TRUE; return (attrstr); } /*---------------------------------------------------------------------- ParseCSSBorderTop : parse a CSS BorderTop attribute string. ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSBorderTop (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSBorderTop (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { MSG ("ParseCSSBorderTop "); TODO return (attrstr); } /*---------------------------------------------------------------------- ParseCSSBorderRight : parse a CSS BorderRight attribute string. ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSBorderRight (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSBorderRight (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { MSG ("ParseCSSBorderRight "); TODO parsedrule=TRUE; return (attrstr); } /*---------------------------------------------------------------------- ParseCSSBorderBottom : parse a CSS BorderBottom attribute string. ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSBorderBottom (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSBorderBottom (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { MSG ("ParseCSSBorderBottom "); TODO parsedrule=TRUE; return (attrstr); } /*---------------------------------------------------------------------- ParseCSSBorderLeft : parse a CSS BorderLeft attribute string. ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSBorderLeft (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSBorderLeft (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { MSG ("ParseCSSBorderLeft "); TODO parsedrule=TRUE; return (attrstr); } /*---------------------------------------------------------------------- ParseCSSBorderColor : parse a CSS border-color attribute string. ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSBorderColor (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSBorderColor (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { MSG ("ParseCSSBorderColor "); TODO parsedrule=TRUE; return (attrstr); } /*---------------------------------------------------------------------- ParseCSSBorderStyle : parse a CSS border-style attribute string. ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSBorderStyle (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSBorderStyle (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { MSG ("ParseCSSBorderStyle "); TODO parsedrule=TRUE; return (attrstr); } /*---------------------------------------------------------------------- ParseCSSBorder : parse a CSS border attribute string. ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSBorder (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSBorder (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { MSG ("ParseCSSBorder "); TODO parsedrule=TRUE; return (attrstr); } /*---------------------------------------------------------------------- ParseCSSClear : parse a CSS clear attribute string ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSClear (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSClear (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { MSG ("ParseCSSClear "); TODO parsedrule=TRUE; return (attrstr); } /*---------------------------------------------------------------------- ParseCSSDisplay : parse a CSS display attribute string ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSDisplay (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSDisplay (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { PresentationValue pval; SKIP_BLANK (attrstr); if (IS_WORD (attrstr, "block")) { pval.typed_data.unit = DRIVERP_UNIT_REL; pval.typed_data.value = DRIVERP_NOTINLINE; if (context->drv->SetInLine) context->drv->SetInLine (target, context, pval); SKIP_WORD (attrstr); parsedrule=TRUE; } else if (IS_WORD (attrstr, "inline")) { pval.typed_data.unit = DRIVERP_UNIT_REL; pval.typed_data.value = DRIVERP_INLINE; if (context->drv->SetInLine) context->drv->SetInLine (target, context, pval); SKIP_WORD (attrstr); parsedrule=TRUE; } else if (IS_WORD (attrstr, "none")) { pval.typed_data.unit = DRIVERP_UNIT_REL; pval.typed_data.value = DRIVERP_HIDE; if (context->drv->SetShow) context->drv->SetShow (target, context, pval); SKIP_WORD (attrstr); parsedrule=TRUE; } else if (IS_WORD (attrstr, "list-item")) { MSG ("list-item display value unsupported\n"); SKIP_WORD (attrstr); parsedrule=FALSE; } else { fprintf (stderr, "invalid display value %s\n", attrstr); return (attrstr); parsedrule=FALSE; } return (attrstr); } /*---------------------------------------------------------------------- ParseCSSFloat : parse a CSS float attribute string ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSFloat (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSFloat (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { MSG ("ParseCSSFloat "); TODO parsedrule=TRUE; return (attrstr); } /*---------------------------------------------------------------------- ParseCSSLetterSpacing : parse a CSS letter-spacing attribute string. ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSLetterSpacing (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSLetterSpacing (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { MSG ("ParseCSSLetterSpacing "); TODO parsedrule=TRUE; return (attrstr); } /*---------------------------------------------------------------------- ParseCSSListStyleType : parse a CSS list-style-type attribute string. ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSListStyleType (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSListStyleType (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { MSG ("ParseCSSListStyleType "); TODO parsedrule=TRUE; return (attrstr); } /*---------------------------------------------------------------------- ParseCSSListStyleImage : parse a CSS list-style-image attribute string. ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSListStyleImage (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSListStyleImage (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { MSG ("ParseCSSListStyleImage "); TODO parsedrule=TRUE; return (attrstr); } /*---------------------------------------------------------------------- ParseCSSListStylePosition : parse a CSS list-style-position attribute string. ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSListStylePosition (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSListStylePosition (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { MSG ("ParseCSSListStylePosition "); TODO parsedrule=TRUE; return (attrstr); } /*---------------------------------------------------------------------- ParseCSSListStyle : parse a CSS list-style attribute string. ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSListStyle (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSListStyle (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { MSG ("ParseCSSListStyle "); TODO parsedrule=TRUE; return (attrstr); } /*---------------------------------------------------------------------- ParseCSSMarginLeft : parse a CSS margin-left attribute string. ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSMarginLeft (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSMarginLeft (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { MSG ("ParseCSSMarginLeft "); TODO parsedrule=TRUE; return (attrstr); } /*---------------------------------------------------------------------- ParseCSSMarginRight : parse a CSS margin-right attribute string. ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSMarginRight (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSMarginRight (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { MSG ("ParseCSSMarginRight "); TODO parsedrule=TRUE; return (attrstr); } /*---------------------------------------------------------------------- ParseCSSMargin : parse a CSS margin attribute string. ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSMargin (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSMargin (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { MSG ("ParseCSSMargin "); TODO parsedrule=TRUE; return (attrstr); } /*---------------------------------------------------------------------- ParseCSSPaddingTop : parse a CSS PaddingTop attribute string. ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSPaddingTop (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSPaddingTop (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { MSG ("ParseCSSPaddingTop "); TODO parsedrule=TRUE; return (attrstr); } /*---------------------------------------------------------------------- ParseCSSPaddingRight : parse a CSS PaddingRight attribute string. ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSPaddingRight (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSPaddingRight (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { MSG ("ParseCSSPaddingRight "); TODO parsedrule=TRUE; return (attrstr); } /*---------------------------------------------------------------------- ParseCSSPaddingBottom : parse a CSS PaddingBottom attribute string. ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSPaddingBottom (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSPaddingBottom (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { MSG ("ParseCSSPaddingBottom "); TODO parsedrule=TRUE; return (attrstr); } /*---------------------------------------------------------------------- ParseCSSPaddingLeft : parse a CSS PaddingLeft attribute string. ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSPaddingLeft (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSPaddingLeft (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { MSG ("ParseCSSPaddingLeft "); TODO parsedrule=TRUE; return (attrstr); } /*---------------------------------------------------------------------- ParseCSSPadding : parse a CSS padding attribute string. ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSPadding (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSPadding (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { MSG ("ParseCSSPadding "); TODO parsedrule=TRUE; return (attrstr); } /*---------------------------------------------------------------------- ParseCSSTextAlign : parse a CSS text-align attribute string. ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSTextAlign (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSTextAlign (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { PresentationValue align; PresentationValue justify; align.typed_data.value = 0; align.typed_data.unit = 1; justify.typed_data.value = 0; justify.typed_data.unit = 1; SKIP_BLANK (attrstr); if (IS_WORD (attrstr, "left")) { align.typed_data.value = AdjustLeft; SKIP_WORD (attrstr); parsedrule=TRUE; } else if (IS_WORD (attrstr, "right")) { align.typed_data.value = AdjustRight; SKIP_WORD (attrstr); parsedrule=TRUE; } else if (IS_WORD (attrstr, "center")) { align.typed_data.value = Centered; SKIP_WORD (attrstr); parsedrule=TRUE; } else if (IS_WORD (attrstr, "justify")) { justify.typed_data.value = Justified; SKIP_WORD (attrstr); parsedrule=TRUE; } else { fprintf (stderr, "invalid align value\n"); return (attrstr); parsedrule=FALSE; } /* * install the new presentation. */ if (align.typed_data.value) { if (context->drv->SetAlignment) context->drv->SetAlignment (target, context, align); } if (justify.typed_data.value) { if (context->drv->SetJustification) context->drv->SetJustification (target, context, justify); if (context->drv->SetHyphenation) context->drv->SetHyphenation (target, context, justify); } return (attrstr); } /*---------------------------------------------------------------------- ParseCSSTextIndent : parse a CSS text-indent attribute string. ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSTextIndent (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSTextIndent (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { PresentationValue pval; SKIP_BLANK (attrstr); attrstr = ParseCssUnit (attrstr, &pval); if (pval.typed_data.unit == DRIVERP_UNIT_INVALID) { fprintf (stderr, "invalid font size\n"); parsedrule=FALSE; return (attrstr); } /* * install the attribute */ parsedrule=TRUE; if (context->drv->SetIndent != NULL) { context->drv->SetIndent (target, context, pval); } return (attrstr); } /*---------------------------------------------------------------------- ParseCSSTextTransform : parse a CSS text-transform attribute string. ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSTextTransform (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSTextTransform (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { MSG ("ParseCSSTextTransform "); TODO return (attrstr); } /*---------------------------------------------------------------------- ParseCSSVerticalAlign : parse a CSS vertical-align attribute string. ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSVerticalAlign (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSVerticalAlign (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { MSG ("ParseCSSVerticalAlign "); TODO parsedrule=TRUE; return (attrstr); } /*---------------------------------------------------------------------- ParseCSSWhiteSpace : parse a CSS white-space attribute string. ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSWhiteSpace (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSWhiteSpace (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { SKIP_BLANK (attrstr); if (IS_WORD (attrstr, "normal")) { parsedrule=TRUE; SKIP_WORD (attrstr); } else if (IS_WORD (attrstr, "pre")) { MSG ("pre white-space setting unsupported\n"); SKIP_WORD (attrstr); parsedrule=FALSE; } else { fprintf (stderr, "invalid white-space value %s\n", attrstr); parsedrule=FALSE; return (attrstr); } return (attrstr); } /*---------------------------------------------------------------------- ParseCSSWordSpacing : parse a CSS word-spacing attribute string. ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSWordSpacing (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSWordSpacing (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { MSG ("ParseCSSWordSpacing "); TODO parsedrule=TRUE; return (attrstr); } /*---------------------------------------------------------------------- ParseCSSFont : parse a CSS font attribute string we expect the input string describing the attribute to be !!!!!! ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSFont (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSFont (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { MSG ("ParseCSSFont "); TODO parsedrule=TRUE; return (attrstr); } /*---------------------------------------------------------------------- ParseCSSFontSize : parse a CSS font size attr string we expect the input string describing the attribute to be xx-small, x-small, small, medium, large, x-large, xx-large or an absolute size, or an imcrement relative to the parent ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSFontSize (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSFontSize (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { PresentationValue pval; SKIP_BLANK (attrstr); if (IS_WORD (attrstr, "xx-small")) { #ifdef STYLE_DEBUG fprintf(stderr, " recognized xx-small, "); #endif pval.typed_data.unit = DRIVERP_UNIT_REL; pval.typed_data.value = 1; SKIP_WORD (attrstr); attrstr++; /* step over the "-" and skip "small" */ SKIP_WORD (attrstr); parsedrule=TRUE; } else if (IS_WORD (attrstr, "x-small")) { #ifdef STYLE_DEBUG fprintf(stderr, " recognized x-small, "); #endif pval.typed_data.unit = DRIVERP_UNIT_REL; pval.typed_data.value = 2; SKIP_WORD (attrstr); attrstr++; /* step over the "-" and skip "small" */ SKIP_WORD (attrstr); parsedrule=TRUE; } else if (IS_WORD (attrstr, "small")) { #ifdef STYLE_DEBUG fprintf(stderr, " recognized small, "); #endif pval.typed_data.unit = DRIVERP_UNIT_REL; pval.typed_data.value = 3; SKIP_WORD (attrstr); parsedrule=TRUE; } else if (IS_WORD (attrstr, "medium")) { #ifdef STYLE_DEBUG fprintf(stderr, " recognized medium, "); #endif pval.typed_data.unit = DRIVERP_UNIT_REL; pval.typed_data.value = 4; SKIP_WORD (attrstr); parsedrule=TRUE; } else if (IS_WORD (attrstr, "large")) { #ifdef STYLE_DEBUG fprintf(stderr, " recognized large, "); #endif pval.typed_data.unit = DRIVERP_UNIT_REL; pval.typed_data.value = 5; SKIP_WORD (attrstr); parsedrule=TRUE; } else if (IS_WORD (attrstr, "x-large")) { #ifdef STYLE_DEBUG fprintf(stderr, " recognized x-large, "); #endif pval.typed_data.unit = DRIVERP_UNIT_REL; pval.typed_data.value = 6; SKIP_WORD (attrstr); attrstr++; /* step over the "-" and skip "large" */ SKIP_WORD (attrstr); parsedrule=TRUE; } else if (IS_WORD (attrstr, "xx-large")) { #ifdef STYLE_DEBUG fprintf(stderr, " recognized xx-large, "); #endif pval.typed_data.unit = DRIVERP_UNIT_REL; pval.typed_data.value = 8; SKIP_WORD (attrstr); attrstr++; /* step over the "-" and skip "large" */ SKIP_WORD (attrstr); parsedrule=TRUE; } else { attrstr = ParseCssUnit (attrstr, &pval); parsedrule=TRUE; if (pval.typed_data.unit == DRIVERP_UNIT_INVALID) { #ifdef STYLE_DEBUG fprintf(stderr, " unrecognized value, "); #endif TtaDisplaySimpleMessage (INFO, CssMsgTable, CSS_INVALID_UNIT); parsedrule=FALSE; return (attrstr); } #ifdef STYLE_DEBUG else fprintf(stderr, " recognized a unit, "); #endif } /* * install the attribute */ if (context->drv->SetFontSize) context->drv->SetFontSize (target, context, pval); return (attrstr); } /*---------------------------------------------------------------------- ParseCSSFontFamily : parse a CSS font family string we expect the input string describing the attribute to be a common generic font style name ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSFontFamily (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSFontFamily (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { PresentationValue font; font.typed_data.value = 0; font.typed_data.unit = 1; SKIP_BLANK (attrstr); if (IS_CASE_WORD (attrstr, "times")) { #ifdef STYLE_DEBUG fprintf(stderr, " recognized times, "); #endif font.typed_data.value = DRIVERP_FONT_TIMES; SKIP_PROPERTY (attrstr); parsedrule=TRUE; } else if (IS_CASE_WORD (attrstr, "serif")) { #ifdef STYLE_DEBUG fprintf(stderr, " recognized serif, "); #endif font.typed_data.value = DRIVERP_FONT_TIMES; SKIP_PROPERTY (attrstr); parsedrule=TRUE; } else if (IS_CASE_WORD (attrstr, "helvetica")) { #ifdef STYLE_DEBUG fprintf(stderr, " recognized helvetica, "); #endif font.typed_data.value = DRIVERP_FONT_HELVETICA; SKIP_PROPERTY (attrstr); parsedrule=TRUE; } else if (IS_CASE_WORD (attrstr, "sans-serif")) { #ifdef STYLE_DEBUG fprintf(stderr, " recognized sans-serif, "); #endif font.typed_data.value = DRIVERP_FONT_HELVETICA; SKIP_PROPERTY (attrstr); parsedrule=TRUE; } else if (IS_CASE_WORD (attrstr, "courier")) { #ifdef STYLE_DEBUG fprintf(stderr, " recognized courier, "); #endif font.typed_data.value = DRIVERP_FONT_COURIER; SKIP_PROPERTY (attrstr); parsedrule=TRUE; } else if (IS_CASE_WORD (attrstr, "monospace")) { #ifdef STYLE_DEBUG fprintf(stderr, " recognized monospace, "); #endif font.typed_data.value = DRIVERP_FONT_COURIER; SKIP_PROPERTY (attrstr); parsedrule=TRUE; } else { /* !!!!! manque cursive et fantasy !!!!! */ TtaDisplaySimpleMessage (INFO, CssMsgTable, CSS_INVALID_FONT_FAMILY); #ifdef STYLE_DEBUG fprintf(stderr, " invalid font familly, "); #endif SKIP_PROPERTY (attrstr); parsedrule=FALSE; return (attrstr); } /* * install the new presentation. */ if (context->drv->SetFontFamily) context->drv->SetFontFamily (target, context, font); return (attrstr); } /*---------------------------------------------------------------------- ParseCSSFontWeight : parse a CSS font weight string we expect the input string describing the attribute to be extra-light, light, demi-light, medium, demi-bold, bold, extra-bold or a number encoding for the previous values ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSFontWeight (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSFontWeight (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { PresentationValue weight; int val; weight.typed_data.value = 0; weight.typed_data.unit = 1; SKIP_BLANK (attrstr); if (IS_WORD (attrstr, "extra-light")) { #ifdef STYLE_DEBUG fprintf(stderr, " recognized extra-light, "); #endif weight.typed_data.value = -3; SKIP_WORD (attrstr); parsedrule=TRUE; } else if (IS_WORD (attrstr, "light")) { #ifdef STYLE_DEBUG fprintf(stderr, " recognized light, "); #endif weight.typed_data.value = -2; SKIP_WORD (attrstr); parsedrule=TRUE; } else if (IS_WORD (attrstr, "demi-light")) { #ifdef STYLE_DEBUG fprintf(stderr, " recognized demi-light, "); #endif weight.typed_data.value = -1; SKIP_WORD (attrstr); parsedrule=TRUE; } else if (IS_WORD (attrstr, "medium")) { #ifdef STYLE_DEBUG fprintf(stderr, " recognized medium, "); #endif weight.typed_data.value = 0; SKIP_WORD (attrstr); parsedrule=TRUE; } else if (IS_WORD (attrstr, "extra-bold")) { #ifdef STYLE_DEBUG fprintf(stderr, " recognized extra-bold, "); #endif weight.typed_data.value = +3; SKIP_WORD (attrstr); parsedrule=TRUE; } else if (IS_WORD (attrstr, "bold")) { #ifdef STYLE_DEBUG fprintf(stderr, " recognized bold, "); #endif weight.typed_data.value = +2; SKIP_WORD (attrstr); } else if (IS_WORD (attrstr, "demi-bold")) { #ifdef STYLE_DEBUG fprintf(stderr, " recognized demi-bold, "); #endif weight.typed_data.value = +1; SKIP_WORD (attrstr); parsedrule=TRUE; } else if (sscanf (attrstr, "%d", &val) > 0) { parsedrule=TRUE; if ((val < -3) || (val > 3)) { TtaDisplaySimpleMessage (INFO, CssMsgTable, CSS_INVALID_FONT_WEIGHT); #ifdef STYLE_DEBUG fprintf (stderr, "invalid font weight %d\n", val); #endif weight.typed_data.value = 0; parsedrule=FALSE; } else weight.typed_data.value = val; SKIP_INT (attrstr); } else { TtaDisplaySimpleMessage (INFO, CssMsgTable, CSS_INVALID_FONT_WEIGHT); #ifdef STYLE_DEBUG fprintf (stderr, "invalid font weight\n"); #endif parsedrule=FALSE; return (attrstr); } /* * Here we have to reduce since font weight is not well supported * by the Thot presentation API. */ switch (weight.typed_data.value) { case 3: case 2: case 1: weight.typed_data.value = DRIVERP_FONT_BOLD; break; case -3: case -2: case -1: weight.typed_data.value = DRIVERP_FONT_ITALICS; break; } /* * install the new presentation. */ if (context->drv->SetFontStyle) context->drv->SetFontStyle (target, context, weight); return (attrstr); } /*---------------------------------------------------------------------- ParseCSSFontVariant : parse a CSS font variant string we expect the input string describing the attribute to be normal or small-caps ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSFontVariant (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSFontVariant (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { PresentationValue style; style.typed_data.value = 0; style.typed_data.unit = 1; SKIP_BLANK (attrstr); if (IS_WORD (attrstr, "small-caps")) { /* * !!!!! Not supported yet, so we use bold for rendering */ #ifdef STYLE_DEBUG fprintf(stderr, " recognized small-caps, "); #endif style.typed_data.value = DRIVERP_FONT_BOLD; SKIP_WORD (attrstr); parsedrule=TRUE; } else if (IS_WORD (attrstr, "normal")) { #ifdef STYLE_DEBUG fprintf(stderr, " recognized normal, "); #endif style.typed_data.value = DRIVERP_FONT_ROMAN; SKIP_WORD (attrstr); parsedrule=TRUE; } else { TtaDisplaySimpleMessage (INFO, CssMsgTable, CSS_INVALID_FONT_VARIANT); #ifdef STYLE_DEBUG fprintf(stderr, " invalid font variant, "); #endif parsedrule=FALSE; return (attrstr); } /* * install the new presentation. */ if (style.typed_data.value != 0) { PresentationValue previous_style; if ((context->drv->GetFontStyle) && (!context->drv->GetFontStyle (target, context, &previous_style))) { if (previous_style.typed_data.value == DRIVERP_FONT_BOLD) { if (style.typed_data.value == DRIVERP_FONT_ITALICS) style.typed_data.value = DRIVERP_FONT_BOLDITALICS; if (style.typed_data.value == DRIVERP_FONT_OBLIQUE) style.typed_data.value = DRIVERP_FONT_BOLDOBLIQUE; } if (context->drv->SetFontStyle) context->drv->SetFontStyle (target, context, style); } else { if (context->drv->SetFontStyle) context->drv->SetFontStyle (target, context, style); } } return (attrstr); } /*---------------------------------------------------------------------- ParseCSSFontStyle : parse a CSS font style string we expect the input string describing the attribute to be italic, oblique or normal ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSFontStyle (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSFontStyle (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { PresentationValue style; PresentationValue size; style.typed_data.value = 0; style.typed_data.unit = 1; size.typed_data.value = 0; size.typed_data.unit = 1; SKIP_BLANK (attrstr); if (IS_WORD (attrstr, "italic")) { #ifdef STYLE_DEBUG fprintf(stderr, " recognized italic, "); #endif style.typed_data.value = DRIVERP_FONT_ITALICS; SKIP_WORD (attrstr); parsedrule=TRUE; } else if (IS_WORD (attrstr, "oblique")) { #ifdef STYLE_DEBUG fprintf(stderr, " recognized oblique, "); #endif style.typed_data.value = DRIVERP_FONT_OBLIQUE; SKIP_WORD (attrstr); parsedrule=TRUE; } else if (IS_WORD (attrstr, "normal")) { #ifdef STYLE_DEBUG fprintf(stderr, " recognized normal, "); #endif style.typed_data.value = DRIVERP_FONT_ROMAN; SKIP_WORD (attrstr); parsedrule=TRUE; } else { TtaDisplaySimpleMessage (INFO, CssMsgTable, CSS_INVALID_FONT_STYLE); #ifdef STYLE_DEBUG fprintf(stderr, " invalid font style, "); #endif parsedrule=FALSE; return (attrstr); } /* * install the new presentation. */ if (style.typed_data.value != 0) { PresentationValue previous_style; if ((context->drv->GetFontStyle) && (!context->drv->GetFontStyle (target, context, &previous_style))) { if (previous_style.typed_data.value == DRIVERP_FONT_BOLD) { if (style.typed_data.value == DRIVERP_FONT_ITALICS) style.typed_data.value = DRIVERP_FONT_BOLDITALICS; if (style.typed_data.value == DRIVERP_FONT_OBLIQUE) style.typed_data.value = DRIVERP_FONT_BOLDOBLIQUE; } if (context->drv->SetFontStyle) context->drv->SetFontStyle (target, context, style); } else { if (context->drv->SetFontStyle) context->drv->SetFontStyle (target, context, style); } } if (size.typed_data.value != 0) { PresentationValue previous_size; if ((context->drv->GetFontSize) && (!context->drv->GetFontSize (target, context, &previous_size))) { /* !!!!!!!!!!!!!!!!!!!!!!!! Unite + relatif !!!!!!!!!!!!!!!! */ size.typed_data.value += previous_size.typed_data.value; if (context->drv->SetFontSize) context->drv->SetFontSize (target, context, size); } else { size.typed_data.value = 10; if (context->drv->SetFontSize) context->drv->SetFontSize (target, context, size); } } return (attrstr); } /*---------------------------------------------------------------------- ParseCSSLineSpacing : parse a CSS font leading string we expect the input string describing the attribute to be value% or value ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSLineSpacing (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSLineSpacing (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { PresentationValue lead; attrstr = ParseCssUnit (attrstr, &lead); if (lead.typed_data.unit == DRIVERP_UNIT_INVALID) { TtaDisplaySimpleMessage (INFO, CssMsgTable, CSS_INVALID_LINE_SPACING); #ifdef STYLE_DEBUG fprintf(stderr, " invalid line spacing, "); #endif parsedrule=FALSE; return (attrstr); } parsedrule=TRUE; /* * install the new presentation. */ if (context->drv->SetLineSpacing) context->drv->SetLineSpacing (target, context, lead); return (attrstr); } /*---------------------------------------------------------------------- ParseCSSTextDecoration : parse a CSS text decor string we expect the input string describing the attribute to be underline, overline, line-through, box, shadowbox, box3d, cartouche, blink or none ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSTextDecoration (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSTextDecoration (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { PresentationValue decor; decor.typed_data.value = 0; decor.typed_data.unit = 1; SKIP_BLANK (attrstr); if (IS_WORD (attrstr, "underline")) { decor.typed_data.value = Underline; SKIP_WORD (attrstr); parsedrule=TRUE; } else if (IS_WORD (attrstr, "overline")) { decor.typed_data.value = Overline; SKIP_WORD (attrstr); parsedrule=TRUE; } else if (IS_WORD (attrstr, "line-through")) { decor.typed_data.value = CrossOut; SKIP_WORD (attrstr); } else if (IS_WORD (attrstr, "box")) { MSG ("the box text-decoration attribute is not yet supported\n"); SKIP_WORD (attrstr); parsedrule=TRUE; } else if (IS_WORD (attrstr, "boxshadow")) { MSG ("the boxshadow text-decoration attribute is not yet supported\n"); SKIP_WORD (attrstr); parsedrule=TRUE; } else if (IS_WORD (attrstr, "box3d")) { MSG ("the box3d text-decoration attribute is not yet supported\n"); SKIP_WORD (attrstr); parsedrule=TRUE; } else if (IS_WORD (attrstr, "cartouche")) { MSG ("the cartouche text-decoration attribute is not yet supported\n"); SKIP_WORD (attrstr); parsedrule=TRUE; } else if (IS_WORD (attrstr, "blink")) { MSG ("the blink text-decoration attribute will not be supported\n"); SKIP_WORD (attrstr); parsedrule=TRUE; } else if (IS_WORD (attrstr, "none")) { decor.typed_data.value = NoUnderline; SKIP_WORD (attrstr); parsedrule=TRUE; } else { TtaDisplaySimpleMessage (INFO, CssMsgTable, CSS_INVALID_TEXT_DECO); #ifdef STYLE_DEBUG fprintf(stderr, " invalid text decoration, "); #endif parsedrule=FALSE; return (attrstr); } /* * install the new presentation. */ if (decor.typed_data.value) { if (context->drv->SetTextUnderlining) context->drv->SetTextUnderlining (target, context, decor); } return (attrstr); } /*---------------------------------------------------------------------- ParseCSSColor : parse a CSS color attribute string we expect the input string describing the attribute to be either a color name, a 3 tuple or an hexadecimal encoding. The color used will be approximed from the current color table ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSColor (char *attrstr, PresentationValue * val) #else static char *ParseCSSColor (attrstr, val) char *attrstr; PresentationValue *val; #endif { char colname[100]; unsigned short redval = (unsigned short) -1; unsigned short greenval = 0; /* composant of each RGB */ unsigned short blueval = 0; /* default to red if unknown ! */ int i; int best = 0; /* best color in list found */ SKIP_BLANK (attrstr); val->typed_data.unit = DRIVERP_UNIT_INVALID; val->typed_data.value = 0; /* * first parse the attribute string * NOTE : this can't lookup for color name in * cause we try first to lokup color name from digits * [0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f] */ if ((*attrstr == '#') || (isxdigit (attrstr[0]) && isxdigit (attrstr[1]) && isxdigit (attrstr[2]))) { if (*attrstr == '#') attrstr++; /* * we expect an hexa encoding like F00 or FF0000. */ if ((!isxdigit (attrstr[0])) || (!isxdigit (attrstr[1])) || (!isxdigit (attrstr[2]))) { TtaDisplaySimpleMessage (INFO, CssMsgTable, CSS_INVALID_COLOR_ENCODING); #ifdef STYLE_DEBUG fprintf(stderr, " invalid color encoding, "); #endif goto failed; } else if (!isxdigit (attrstr[3])) { /* * encoded as on 3 digits #F0F */ redval = hexa_val (attrstr[0]) * 16 + hexa_val (attrstr[0]); greenval = hexa_val (attrstr[1]) * 16 + hexa_val (attrstr[1]); blueval = hexa_val (attrstr[2]) * 16 + hexa_val (attrstr[2]); attrstr += 3; } else { if ((!isxdigit (attrstr[4])) || (!isxdigit (attrstr[5]))) { TtaDisplaySimpleMessage (INFO, CssMsgTable, CSS_INVALID_COLOR_ENCODING); #ifdef STYLE_DEBUG fprintf(stderr, " invalid color encoding, "); #endif } else { /* * encoded as on 3 digits #FF00FF */ redval = hexa_val (attrstr[0]) * 16 + hexa_val (attrstr[1]); greenval = hexa_val (attrstr[2]) * 16 + hexa_val (attrstr[3]); blueval = hexa_val (attrstr[4]) * 16 + hexa_val (attrstr[5]); attrstr += 6; } } goto found_RGB; } else if (isalpha (*attrstr)) { /* * we expect a color name like "red", store it in colname. */ for (i = 0; i < sizeof (colname) - 1; i++) { if (!(isalnum (attrstr[i]))) { attrstr += i; break; } colname[i] = attrstr[i]; } colname[i] = 0; /* * Lookup the color name in Thot color name database */ TtaGiveRGB (colname, &redval, &greenval, &blueval); goto found_RGB; } else if ((isdigit (*attrstr)) || (*attrstr == '.')) { /* * we expect a color defined by it's three components. * like "255 0 0" or "1.0 0.0 0.0" TODO */ } failed: val->typed_data.unit = DRIVERP_UNIT_INVALID; val->typed_data.value = 0; return (attrstr); found_RGB: best = TtaGetThotColor (redval, greenval, blueval); val->typed_data.value = best; val->typed_data.unit = DRIVERP_UNIT_REL; return (attrstr); } /*---------------------------------------------------------------------- ParseCSSWidth : parse a CSS width attribute ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSWidth (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSWidth (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { SKIP_BLANK (attrstr); /* * first parse the attribute string */ if (!strcasecmp (attrstr, "auto")) { SKIP_WORD (attrstr); MSG ("ParseCSSWidth : auto "); TODO; parsedrule=TRUE; return (attrstr); } /* * install the new presentation. mainview = TtaGetViewFromName(doc, "Document_View"); TtaGiveBoxSize(elem, doc, mainview, UnPoint, &width, &height); new_height = height; TtaChangeBoxSize(elem doc, mainview, 0, new_height - height, UnPoint); */ parsedrule=TRUE; return (attrstr); } /*---------------------------------------------------------------------- ParseCSSMarginTop : parse a CSS margin-top attribute ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSMarginTop (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSMarginTop (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { PresentationValue margin; SKIP_BLANK (attrstr); /* * first parse the attribute string */ attrstr = ParseCssUnit (attrstr, &margin); if (margin.typed_data.unit == DRIVERP_UNIT_INVALID) { TtaDisplaySimpleMessage (INFO, CssMsgTable, CSS_INVALID_MARGIN_TOP); #ifdef STYLE_DEBUG fprintf(stderr, " invalid margin top, "); #endif parsedrule=FALSE; return (attrstr); } parsedrule=TRUE; if (context->drv->SetVPos) context->drv->SetVPos (target, context, margin); return (attrstr); } /*---------------------------------------------------------------------- ParseCSSMarginBottom : parse a CSS margin-bottom attribute ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSMarginBottom (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSMarginBottom (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { PresentationValue margin; SKIP_BLANK (attrstr); /* * first parse the attribute string */ attrstr = ParseCssUnit (attrstr, &margin); if (margin.typed_data.unit == DRIVERP_UNIT_INVALID) { TtaDisplaySimpleMessage (INFO, CssMsgTable, CSS_INVALID_MARGIN_BOTTOM); #ifdef STYLE_DEBUG fprintf(stderr, " invalid margin bottom, "); #endif parsedrule=FALSE; return (attrstr); } parsedrule=TRUE ; if (context->drv->SetVPos) context->drv->SetVPos (target, context, margin); return (attrstr); } /*---------------------------------------------------------------------- ParseCSSHeight : parse a CSS height attribute ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSHeight (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSHeight (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { SKIP_BLANK (attrstr); /* * first parse the attribute string */ if (!strcasecmp (attrstr, "auto")) { SKIP_WORD (attrstr); MSG ("ParseCSSHeight : auto "); TODO; parsedrule= TRUE ; return (attrstr); } parsedrule=TRUE ; /* * read the value, and if necessary convert to point size attrstr = ParseCssUnit(attrstr, &new_height, &unit); */ return (attrstr); } /*---------------------------------------------------------------------- ParseCSSForeground : parse a CSS foreground attribute ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSForeground (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSForeground (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { PresentationValue best; attrstr = ParseCSSColor (attrstr, &best); if (best.typed_data.unit == DRIVERP_UNIT_INVALID) { parsedrule=FALSE; return (attrstr); } parsedrule=TRUE; /* * install the new presentation. */ if (context->drv->SetForegroundColor) context->drv->SetForegroundColor (target, context, best); return (attrstr); } /*---------------------------------------------------------------------- ParseCSSBackgroundColor : parse a CSS background color attribute ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSBackgroundColor (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSBackgroundColor (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { ElementType elType; PresentationValue best; GenericContext gblock; boolean setColor; best.typed_data.unit = DRIVERP_UNIT_INVALID; setColor = TRUE; if (IS_CASE_WORD (attrstr, "transparent")) { best.typed_data.value = DRIVERP_PATTERN_NONE; best.typed_data.unit = DRIVERP_UNIT_REL; if (context->drv->SetFillPattern) context->drv->SetFillPattern (target, context, best); parsedrule=TRUE ; return (attrstr); } attrstr = ParseCSSColor (attrstr, &best); if (best.typed_data.unit == DRIVERP_UNIT_INVALID) setColor = FALSE; if (setColor) { if (setColor) { /* install the new presentation. */ if (context->drv->SetBackgroundColor) context->drv->SetBackgroundColor (target, context, best); /* thot specificity : need to set fill pattern for background color */ best.typed_data.value = DRIVERP_PATTERN_BACKGROUND; best.typed_data.unit = DRIVERP_UNIT_REL; if (context->drv->SetFillPattern) context->drv->SetFillPattern (target, context, best); best.typed_data.value = 1; best.typed_data.unit = DRIVERP_UNIT_REL; if (context->drv->SetShowBox) context->drv->SetShowBox (target, context, best); } } parsedrule=TRUE ; return (attrstr); } /*---------------------------------------------------------------------- ParseCSSBackgroundImageCallback : Callback called asynchronously by FetchImage when a background image has been fetched. ----------------------------------------------------------------------*/ typedef struct _BackgroundImageCallbackBlock { PresentationTarget target; union { PresentationContextBlock blk; GenericContextBlock generic; } context; } BackgroundImageCallbackBlock, *BackgroundImageCallbackPtr; #ifdef __STDC__ void ParseCSSBackgroundImageCallback (Document doc, Element el, char *file, void *extra) #else void ParseCSSBackgroundImageCallback (doc, el, file, extra) Document doc; Element el; char *file; void *extra; #endif { BackgroundImageCallbackPtr callblock = (BackgroundImageCallbackPtr) extra; PresentationTarget target; PresentationContext context; PresentationValue image; PresentationValue repeat; PresentationValue unused, value; parsedrule=TRUE ; if (callblock == NULL) return; target = callblock->target; context = &callblock->context.blk; /* * Ok the image was fetched, finish the background-image handling. */ image.pointer = file; if (context->drv->SetBgImage) context->drv->SetBgImage (target, context, image); /* * If there is no default repeat mode, enforce a V-Repeat */ if (context->drv->GetPictureMode && context->drv->SetPictureMode) { if (context->drv->GetPictureMode(target, context, &repeat) < 0) { repeat.typed_data.value = DRIVERP_REPEAT; repeat.typed_data.unit = DRIVERP_UNIT_REL; context->drv->SetPictureMode (target, context, repeat); } } /* * If there is no default repeat mode, enforce a V-Repeat */ if (context->drv->SetShowBox) { value.typed_data.value = 1; value.typed_data.unit = DRIVERP_UNIT_REL; context->drv->SetShowBox (target, context, value); } /* * Update the Document header if this is a generic rule */ if (context->drv == &GenericStrategy) /* RebuildHTMLStyleHeader(doc)!!!!!*/; /* * Update the rendering. */ if (context->drv->UpdatePresentation != NULL) context->drv->UpdatePresentation (target, context, unused); TtaFreeMemory(callblock); } /*---------------------------------------------------------------------- ParseCSSBackgroundImage : parse a CSS BackgroundImage attribute string. ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSBackgroundImage (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSBackgroundImage (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { Element el; GenericContext gblock; char *url; BackgroundImageCallbackPtr callblock; PresentationValue image, value; char *no_bg_image; url = NULL; if (! IS_CASE_WORD (attrstr, "url")) return (attrstr); #if 0 /* !!!!! */ attrstr = ParseHTMLURL (attrstr, &url); #endif /* 0 !!!!! */ if (context->destroy == 1) { /* remove the background image PRule */ image.pointer = NULL; if (context->drv->SetBgImage) context->drv->SetBgImage (target, context, image); if (context->drv->GetFillPattern) { if (context->drv->GetFillPattern (target, context, &value) < 0) /* there is no FillPattern rule -> remove ShowBox rule */ if (context->drv->SetShowBox) { value.typed_data.value = 1; value.typed_data.unit = DRIVERP_UNIT_REL; context->drv->SetShowBox (target, context, value); } } } else { if (url) { no_bg_image = TtaGetEnvString("NO_BG_IMAGES"); if ((no_bg_image != NULL) && ((!(strcasecmp(no_bg_image,"yes"))) || (!(strcasecmp(no_bg_image,"true"))))) return (attrstr); /* * if the background is set on the HTML or BODY element, * set the background color for the full window. */ if (context->drv == &GenericStrategy) { gblock = (GenericContext) context; callblock = (BackgroundImageCallbackPtr) TtaGetMemory(sizeof(BackgroundImageCallbackBlock)); if (callblock != NULL) { callblock->target = target; memcpy(&callblock->context.generic, gblock, sizeof(GenericContextBlock)); /* fetch and display background image of element */ el = TtaGetMainRoot (gblock->doc); #if 0 /* !!!!! */ FetchImage (gblock->doc, el, url, 0, ParseCSSBackgroundImageCallback, callblock); #endif /* 0 !!!!! */ } } } if (url) TtaFreeMemory (url); } return (attrstr); } /*---------------------------------------------------------------------- ParseCSSBackgroundRepeat : parse a CSS BackgroundRepeat attribute string. ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSBackgroundRepeat (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSBackgroundRepeat (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { PresentationValue repeat; repeat.typed_data.value = 0; repeat.typed_data.unit = 1; SKIP_BLANK (attrstr); if (IS_WORD (attrstr, "no-repeat")) { repeat.typed_data.value = DRIVERP_SCALE; SKIP_WORD (attrstr); parsedrule=TRUE ; } else if (IS_WORD (attrstr, "repeat-y")) { repeat.typed_data.value = DRIVERP_VREPEAT; SKIP_WORD (attrstr); parsedrule=TRUE ; } else if (IS_WORD (attrstr, "repeat-x")) { repeat.typed_data.value = DRIVERP_HREPEAT; SKIP_WORD (attrstr); parsedrule=TRUE ; } else if (IS_WORD (attrstr, "repeat")) { repeat.typed_data.value = DRIVERP_REPEAT; SKIP_WORD (attrstr); parsedrule=TRUE ; } else { TtaDisplaySimpleMessage (INFO, CssMsgTable, CSS_INVALID_REPEAT); #ifdef STYLE_DEBUG fprintf(stderr, " invalid repeat, "); #endif parsedrule=FALSE; return (attrstr); } /* * install the new presentation. */ if (context->drv->SetPictureMode) context->drv->SetPictureMode (target, context, repeat); return (attrstr); } /*---------------------------------------------------------------------- ParseCSSBackgroundAttachment : parse a CSS BackgroundAttachment attribute string. ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSBackgroundAttachment (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSBackgroundAttachment (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { MSG ("ParseCSSBackgroundAttachment "); TODO parsedrule=TRUE; return (attrstr); } /*---------------------------------------------------------------------- ParseCSSBackgroundPosition : parse a CSS BackgroundPosition attribute string. ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSBackgroundPosition (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSBackgroundPosition (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { MSG ("ParseCSSBackgroundPosition "); TODO parsedrule=TRUE; return (attrstr); } /*---------------------------------------------------------------------- ParseCSSBackground : parse a CSS background attribute ----------------------------------------------------------------------*/ #ifdef __STDC__ static char *ParseCSSBackground (PresentationTarget target, PresentationContext context, char *attrstr) #else static char *ParseCSSBackground (target, context, attrstr) PresentationTarget target; PresentationContext context; char *attrstr; #endif { ElementType elType; Element el; PresentationValue best; GenericContext gblock; char *url; char *no_bg_image; boolean setColor; BackgroundImageCallbackPtr callblock; parsedrule=TRUE; url = NULL; best.typed_data.unit = DRIVERP_UNIT_INVALID; setColor = TRUE; #if 0 /* !!!!! */ if (IS_CASE_WORD (attrstr, "url")) /* * we don't currently support URL just parse it to skip it. */ attrstr = ParseHTMLURL (attrstr, &url); #endif /* 0 !!!!! */ no_bg_image = TtaGetEnvString("NO_BG_IMAGES"); if ((no_bg_image != NULL) && ((!(strcasecmp(no_bg_image,"yes"))) || (!(strcasecmp(no_bg_image,"true"))))) { if (url) TtaFreeMemory (url); url = NULL; } attrstr = ParseCSSColor (attrstr, &best); if (best.typed_data.unit == DRIVERP_UNIT_INVALID) setColor = FALSE; if (url || setColor) { /* install the new presentation. */ if (context->drv->SetBackgroundColor) context->drv->SetBackgroundColor (target, context, best); /* thot specificity : need to set fill pattern for background color */ best.typed_data.value = DRIVERP_PATTERN_BACKGROUND; best.typed_data.unit = DRIVERP_UNIT_REL; if (context->drv->SetFillPattern) context->drv->SetFillPattern (target, context, best); best.typed_data.value = 1; best.typed_data.unit = DRIVERP_UNIT_REL; if (context->drv->SetShowBox) context->drv->SetShowBox (target, context, best); } if (url) TtaFreeMemory (url); return (attrstr); } /************************************************************************ * * * PARSER MAIN FUNCTIONS * * * ************************************************************************/ #if 0 /*---------------------------------------------------------------------- StyleEdit v0.12 : simply calls the CSSFileParser with CSS_FILE as param. ----------------------------------------------------------------------*/ #ifdef __STDC__ void StyleEdit (Document doc, View view) #else void StyleEdit (document, view) Document document; View view; #endif { char *cssfilename; #ifdef STYLE_DEBUG fprintf(stderr, "StyleEdit: enter\n"); #else DisplayMode dm; dm = TtaGetDisplayMode (doc); TtaSetDisplayMode (doc, NoComputedDisplay); #endif DeleteCSS(ListCSS[doc], doc); cssfilename = TtaGetEnvString ("CSSFILE"); if (cssfilename != NULL) CSSFileParser(doc, cssfilename); #ifdef STYLE_DEBUG fprintf(stderr, "StyleEdit: leave\n"); #else TtaSetDisplayMode (doc, dm); #endif } #endif /*---------------------------------------------------------------------- CSSFileParser : is called to read the given file that should contain CSS absolute declarations, recognize them and apply them. params: doc: the document on which the CSS styles are applied CSSFileName: path and name of the file to be parsed. refcss : the css next to which the given css is inserted. if NULL, the css is inserted at the begining. before : tells if the css must be inserted before or after refcss. ----------------------------------------------------------------------*/ #define CSS_CHECK_BUFFER \ { \ if (index >= (buffer_size - 2)) { \ char *new =(char *)TtaRealloc(buffer, buffer_size + 2000); \ if (new == NULL) return; \ buffer_size += 2000; \ buffer = new; \ }} #ifdef __STDC__ void CSSFileParser (Document doc, char *cssfilename, CSSInfoPtr refcss, boolean before) #else void CSSFileParser (document, cssfilename, refcss, before) Document document; char *cssfilename; char *name; CSSInfoPtr refcss; boolean before; #endif { BinFile cssFile; /* CSS File Descriptor */ char curr = NULL; /* current char read from file */ int index = 0; /* where to write in buffer */ char *buffer = NULL; int buffer_size = 2000; boolean comment = FALSE; /* whether the read chars are in a comment */ CSSInfoPtr style; char *name; /* name of the css */ #ifdef STYLE_DEBUG fprintf(stderr, "CSSFileParser: enter\n"); #endif name = GetCSSName(cssfilename); buffer = TtaGetMemory (buffer_size); if (buffer == NULL) { TtaDisplaySimpleMessage (INFO, CssMsgTable, CSS_OUT_OF_MEMORY); return; } if (TtaFileExist(cssfilename)) { cssFile = TtaReadOpen(cssfilename); /* * copying file in a buffer for parser, steping over comments */ if (TtaReadByte(cssFile, &curr)) { while (curr !=EOF) { /* checks for comments end */ if (!comment && (curr == '/')) { if (!TtaReadByte(cssFile, &curr)) break; else if (curr == '*') { /* entering comment */ comment = TRUE; if (!TtaReadByte(cssFile, &curr)) break; continue; } else { /* just a passing '/' */ buffer[index++]='/'; continue; } } /* checks for comments end */ else if (comment && (curr == '*')) { if (!TtaReadByte(cssFile, &curr)) break; else if (curr == '/') { /* leaving comment */ comment = FALSE; if (!TtaReadByte(cssFile, &curr)) break; continue; } else /* just a passing '*' */ continue; } /* nothing special, just copying char if not in comment */ if ( !comment ) buffer[index++]=curr; if (!TtaReadByte(cssFile, &curr)) break; CSS_CHECK_BUFFER } } buffer[index]='\0'; /* errors detection */ if (curr != '\0') TtaDisplaySimpleMessage (INFO, CssMsgTable, CSS_CANT_READ_FILE); else if (comment) TtaDisplaySimpleMessage (INFO, CssMsgTable, CSS_UNCLOSED_COMMENT); TtaReadClose(cssFile); /* * Create a specific Presentation structure for this document * and add it at the end of the list (sorted by increased priority). */ style = GetNewDocumentStyle (doc, name, refcss, before); if (style == NULL) return; style->filename = TtaStrdup(cssfilename); style->schemas = NULL; style->documents[doc] = TRUE; style->css_rule = TtaStrdup (buffer); StyleParser(buffer, doc, TRUE, style); } else /* file doesn't exist */ TtaDisplaySimpleMessage (INFO, CssMsgTable, CSS_FILE_NOT_FOUND); #ifdef STYLE_DEBUG fprintf(stderr, "CSSFileParser: leave\n"); PrintListCSS(stderr); #endif } /*---------------------------------------------------------------------- StyleParser : parse a CSS Style description. We expect the style string to be of the form : List { color: blue } Section { color: pink } params: attrstr : string containing the style rule. doc : document on which the style has to be applied. addrules : whether the rules have to be added in the css rules list style : the CSS Information that will hold the parsed rules ----------------------------------------------------------------------*/ #ifdef __STDC__ void StyleParser (char *attrstr, Document doc, boolean addrules, CSSInfoPtr style) #else void StyleParser (attrstr, doc, addrules, style) char *attrstr; Document doc; boolean addrules; CSSInfoPtr style; #endif { AttributeType newAtType; Attribute newAt; char *decl_end; char saved; #ifdef STYLE_DEBUG fprintf(stderr, " StyleParser: enter [%s]\n", attrstr); #endif /* * now, parse the whole string ... * we need to split it in a set of style declaration. */ SKIP_BLANK (attrstr); while (*attrstr != 0) { SKIP_BLANK (attrstr); decl_end = attrstr; while ((*decl_end != 0) && (*decl_end != '}')) decl_end++; if (*decl_end == 0) { TtaDisplaySimpleMessage (INFO, CssMsgTable, CSS_INVALID_STYLE_HEADER); #ifdef STYLE_DEBUG fprintf (stderr, "Invalid STYLE header : %s\n", attrstr); #endif /* !!!!! save rule as unrecognized */ return; } /* * add a 0 to split, treat the declaration, * put back the char and continue from this point. */ decl_end++; saved = *decl_end; *decl_end = 0; StyleDeclarationParser (attrstr, doc, addrules, style); *decl_end = saved; attrstr = decl_end; SKIP_BLANK (attrstr); } #ifdef STYLE_DEBUG fprintf(stderr, " StyleParser: leave\n"); #endif } /*---------------------------------------------------------------------- StyleDeclarationParser : parse one style declaration stored in the buffer. We expect the style string to be of the form : pinky, awful { color: pink, font-family: helvetica } params: attrstr : string containing the declaration doc : the document on which style is applied addrules : whether the rules have to be added in the css rules list cssInfo : the css info relative to the curent parsed string ----------------------------------------------------------------------*/ #ifdef __STDC__ void StyleDeclarationParser (char *attrstr, Document doc, boolean addrules, CSSInfoPtr cssInfo) #else void StyleDeclarationParser (attrstr, doc, addrules, cssInfo) char *attrstr; Document doc; boolean addrules; CSSInfoPtr cssInfo; #endif { char *decl_end; char *sel_end; char *sel; char sauve1; char sauve2; #ifdef STYLE_DEBUG fprintf(stderr, " StyleDeclarationParser: enter [%s]\n", attrstr); #endif /* * separate the selectors string. */ decl_end = attrstr; while ((*decl_end != 0) && (*decl_end != '{')) decl_end++; if (*decl_end == 0) { TtaDisplaySimpleMessage (INFO, CssMsgTable, CSS_INVALID_STYLE_HEADER); #ifdef STYLE_DEBUG fprintf (stderr, "Invalid STYLE header : %s\n", attrstr); #endif return; } /* * verify and clean the selector string. */ sel_end = decl_end - 1; while (((*(sel_end)) == SPACE) || ((*(sel_end)) == '\b') || ((*(sel_end)) == EOL) || ((*(sel_end)) == '\r')) sel_end--; sel_end++; sauve1 = *sel_end; *sel_end = 0; sel = attrstr; /* * now, deal with the content ... */ decl_end++; attrstr = decl_end; while ((*decl_end != 0) && (*decl_end != '}')) decl_end++; if (*decl_end == 0) { TtaDisplaySimpleMessage (INFO, CssMsgTable, CSS_INVALID_STYLE_DECL); #ifdef STYLE_DEBUG fprintf (stderr, "Invalid STYLE declaration : %s\n", attrstr); #endif return; } sauve2 = *decl_end; *decl_end = 0; /* * parse the style attribute string and install the corresponding * presentation attributes on the new element */ GenericStyleParser (sel, attrstr, doc, addrules, cssInfo); /* restore the string to its original form ! */ *sel_end = sauve1; *decl_end = sauve2; #ifdef STYLE_DEBUG fprintf(stderr, " StyleDeclarationParser: leave\n"); #endif } /*---------------------------------------------------------------------- GenericStyleParser : parse and apply a Style string. This function must be called only to in the context of a generic style applying to class of element. The generic presentation driver is used to reflect the new presentation. params : selector : string containing le list of selectors that will modified by the rule (i.e. first part of the rule). attrstr : string containing the list of attributes and values to apply to the selectors (i.e. second part of the rule) doc : the document on which style is applied addrules : whether the rules have to be added in the css rules list cssInfo : the css info relative to the curent parsed string ----------------------------------------------------------------------*/ #ifdef __STDC__ void GenericStyleParser (char *selector, char *attrstr, Document doc, boolean addrules, CSSInfoPtr cssinfo) #else void GenericStyleParser (selector, attrstr, doc, addrules, cssinfo) char *selector; char *attrstr; Document doc; boolean addrules; CSSInfoPtr cssinfo; #endif { GenericContext ctxt; #ifdef STYLE_DEBUG fprintf (stderr, " GenericStyleParser: enter [%s]\n", attrstr); #endif ctxt = GetGenericContext (doc); if (ctxt == NULL) return; if (HTMLStyleParserDestructiveMode) ctxt->destroy = 1; while ((selector != NULL) && (*selector != 0)) selector = GenericSelectorParser (selector, attrstr, ctxt, doc, addrules, cssinfo); FreeGenericContext (ctxt); #ifdef STYLE_DEBUG fprintf (stderr, " GenericStyleParser: leave\n"); #endif } /*---------------------------------------------------------------------- GenericSelectorParser : Create a generic context for a given selector string. If the selector is made of multiple comma- separated selector items, it parses them one at a time and return the end of the selector string to be handled or NULL params: selector : string containing the selectors list attrstr : list of attibutes and values to be applied on the selector ctxt : generic context used for generic styles editing doc : the document on which style is applied addrules : whether the rules have to be added in the css rules list cssInfo : ptr on the CSSInfo these rules are associated to returns: a string containing the attributes left to parse NOTE: Pseudo-classes are ignored as they can't be interpreted in Thot presentation schemas. Old pseudo-classes analyses are marked with :) smiley in comments. ----------------------------------------------------------------------*/ #ifdef __STDC__ char *GenericSelectorParser (char *selector, char *attrstr, GenericContext ctxt, Document doc, boolean addrules, CSSInfoPtr cssInfo) #else char *GenericSelectorParser (selector, attrstr, ctxt, doc, addrules, cssInfo) char *selector; char *attrstr; GenericContext ctxt; Document doc; boolean addrules; CSSInfoPtr cssInfo; #endif { PSchema gPres; PresentationTarget target; char sel[150]; char class[150]; /* char pseudoclass[150]; unused :) */ char id[150]; char attrelemname[150]; char *deb = &sel[0]; char *elem = &sel[0]; char *cur = &sel[0]; int type, attr, attrval; char *ancestors[MAX_ANCESTORS]; int i, j; PresentationValue unused; SSchema docSchema; /* needed to make rule info */ char *oldselector; /* to copy the selector in rule->rule */ oldselector = selector; #ifdef STYLE_DEBUG fprintf(stderr, " GenericSelectorParser: enter [%s]\n", attrstr); #endif unused.data = 0; for (i = 0; i < MAX_ANCESTORS; i++) { ancestors[i] = NULL; ctxt->ancestors[i] = 0; ctxt->ancestors_nb[i] = 0; } gPres = TtaNewPSchema (); /* * first format the first selector item, uniformizing blanks. */ SKIP_BLANK (selector); sel[0] = 0; class[0] = 0; /* pseudoclass[0] = 0; :) !!!!! */ id[0] = 0; attrelemname[0] = 0; while (1) { /* put one word in the sel buffer */ while ((*selector != 0) && (*selector != ',') && (*selector != '.') && (*selector != ':') && (*selector != '#') && (!IS_BLANK (selector))) *cur++ = *selector++; *cur++ = 0; if ((*selector == ':') || (*selector == '.') || (*selector == '#')) { /* keep the name as attrelemname, it's not an ancestor */ strcpy (attrelemname, elem); elem = ""; } else elem = deb; deb = cur; /* store elem in the list if the string is non-empty */ if (*elem != 0) { for (i = MAX_ANCESTORS - 1; i > 0; i--) ancestors[i] = ancestors[i - 1]; ancestors[0] = elem; } /* why did we stop ? */ if (*selector == 0) /* end of the selector */ break; else if (*selector == ',') { /* end of the current selector */ selector++; break; } else if (*selector == '.') { /* read the class id : only one allowed by selector */ class[0] = 0; cur = &class[0]; selector++; while ((*selector != 0) && (*selector != ',') && (*selector != '.') && (*selector != ':') && (!IS_BLANK (selector))) *cur++ = *selector++; *cur++ = 0; cur = deb; } else if (*selector == ':') { #if 0 /* :) !!!!! */ /* read the pseudoclass id : only one allowed by selector */ pseudoclass[0] = 0; cur = &pseudoclass[0]; selector++; while ((*selector != 0) && (*selector != ',') && (*selector != '.') && (*selector != ':') && (!IS_BLANK (selector))) *cur++ = *selector++; *cur++ = 0; cur = deb; #endif /* :) replaced with: */ TtaDisplaySimpleMessage (INFO, CssMsgTable, CSS_NO_PSEUDOCLASS); #ifdef STYLE_DEBUG fprintf(stderr, " GenericSelectorParser: no pseudoclass please [%s]\n", selector); #endif selector++; break; } else if (*selector == '#') { /* read the id : only one allowed by selector */ id[0] = 0; cur = &id[0]; selector++; while ((*selector != 0) && (*selector != ',') && (*selector != '.') && (*selector != ':') && (!IS_BLANK (selector))) *cur++ = *selector++; *cur++ = 0; cur = deb; } else if (IS_BLANK (selector)) SKIP_BLANK (selector); } elem = ancestors[0]; if ((elem == NULL) || (*elem == 0)) elem = &class[0]; /* if (*elem == 0) elem = &pseudoclass[0]; :) */ if (*elem == 0) elem = &id[0]; if (*elem == 0){ #ifdef STYLE_DEBUG fprintf(stderr, " GenericSelectorParser: leave with [%s], nothing done.\n", selector); #endif return (selector); } /* * set up the context block. */ ctxt->box = 0; #if 0 /* !!!!! no classes with thot */ if (class[0] != 0) { ctxt->class = &class[0]; ctxt->classattr = HTML_ATTR_Class; } else if (pseudoclass[0] != 0) { ctxt->class = &pseudoclass[0]; ctxt->classattr = HTML_ATTR_PseudoClass; } else if (id[0] != 0) { ctxt->class = &id[0]; ctxt->classattr = HTML_ATTR_ID; } else { ctxt->class = NULL; ctxt->classattr = 0; } #endif /* !!!!! */ ctxt->class = NULL; ctxt->classattr = 0; ctxt->type = ctxt->attr = ctxt->attrval = ctxt->attrelem = 0; docSchema = TtaGetDocumentSSchema(doc); if (attrelemname[0] != EOS) { GetTypeFromName (&(ctxt->attrelem), &ctxt->schema, docSchema, attrelemname); /* if (ctxt->attrelem == HTML_EL_BODY) ctxt->attrelem = HTML_EL_HTML; */ } GetTypeFromName (&(ctxt->type), &ctxt->schema, docSchema, elem); if (ctxt->type == 0) { #ifdef STYLE_DEBUG fprintf(stderr, " element %s is of unknown type. \ Leave with [%s]\n", elem, selector); #endif return (selector); } #ifdef STYLE_DEBUG else fprintf(stderr, " element %s is of type %d (schema address:%d)\n", elem, ctxt->type, (int)ctxt->schema); #endif #if 0 /* !!!!! */ if ((ctxt->type == 0) && (ctxt->attr == 0) && (ctxt->attrval == 0) && (ctxt->classattr == 0)) { ctxt->class = elem; ctxt->classattr = HTML_ATTR_Class; } #endif /* 0 !!!!! */ if (ctxt->class != NULL) i = 0; else i = 1; for (; i < MAX_ANCESTORS; i++) { if (ancestors[i] == NULL) break; type = attr = attrval = 0; GetTypeFromName (&type, NULL, docSchema, ancestors[i]); #ifdef STYLE_DEBUG fprintf(stderr, " ancestor %s is of type %d (schema address:%d)\n", ancestors[i], type, (int)ctxt->schema); #endif if (type == 0) continue; for (j = 0; j < MAX_ANCESTORS; j++) { if (ctxt->ancestors[j] == 0) { ctxt->ancestors[j] = type; ctxt->ancestors_nb[j] = 0; break; } if (ctxt->ancestors[j] == type) { ctxt->ancestors_nb[j]++; break; } } } gPres = GetRulePSchema(ctxt->schema, doc, cssInfo); target = (PresentationTarget) gPres; if (attrstr) StyleDeclParser (target, (PresentationContext) ctxt, oldselector, attrstr, addrules, cssInfo); #ifdef STYLE_DEBUG fprintf(stderr, " GenericSelectorParser: leave with [%s]\n", selector); #endif return (selector); } /*---------------------------------------------------------------------- StyleDeclParser : parse a CSS Style string. we expect the input string describing the style to be of the form : ATTRIBUTE : DESCRIPTION [ , ATTIBUTE : DESCRIPTION ] * but tolerate incorrect or incomplete input ----------------------------------------------------------------------*/ #ifdef __STDC__ void StyleDeclParser (PresentationTarget target, PresentationContext context, char *selector, char *attrstr, boolean addrules, CSSInfoPtr cssInfo) #else void StyleDeclParser (target, context, selector, attrstr, addrules, cssInfo) PresentationTarget target; PresentationContext context; char *attrstr; char *selector; boolean addrules; CSSInfoPtr cssInfo; #endif { int styleno; char *new; PresentationValue unused; CSSRulePtr rule; /* the rule */ int noupdate; #ifdef STYLE_DEBUG fprintf(stderr, " StyleDeclParser: enter [%s]\n", attrstr); #endif while (*attrstr != 0) { SKIP_BLANK (attrstr); /* creates the css rule */ rule = NewRule(); rule->cssSSchema = ((GenericContext)context)->schema; rule->eltype = ((GenericContext)context)->type; rule->rule = CollapseRuleStrings(selector, attrstr); /* look for the type of attribute */ new = GetCSSStyleAttrIndex (attrstr, &styleno); if (!new) { attrstr++; SKIP_WORD (attrstr); SKIP_BLANK (attrstr); continue; } /* * update index and skip the ":" indicator if present */ attrstr = new; SKIP_BLANK (attrstr); if (START_DESCR (attrstr)) { attrstr++; SKIP_BLANK (attrstr); } /* * try to parse the value associated to this attribute. */ if (CSSStyleAttributes[styleno].parsing_function != NULL){ #ifdef STYLE_DEBUG fprintf(stderr, " Parsing a %s ...", CSSStyleAttributes[styleno].name); #endif new = CSSStyleAttributes[styleno]. parsing_function (target, context, attrstr); #ifdef STYLE_DEBUG fprintf(stderr, " returned [%s] \n", new); #endif } /* * Update the rendering. */ if (parsedrule && (context->drv->UpdatePresentation != NULL)) { #ifdef STYLE_DEBUG fprintf(stderr, " applying..."); #endif noupdate = context->drv->UpdatePresentation (target, context, unused); #ifdef STYLE_DEBUG fprintf(stderr, (noupdate ? " ***failed***\n" : " done\n")); #endif } if (addrules) if (parsedrule) InsertRule(rule, cssInfo); else InsertBadRule(rule, cssInfo); /* * update index and skip the ";" separator if present */ attrstr = new; SKIP_BLANK (attrstr); if (IS_SEPARATOR (attrstr)) { attrstr++; SKIP_BLANK (attrstr); } } #ifdef STYLE_DEBUG fprintf(stderr, " StyleDeclParser: leave\n"); #endif } /*---------------------------------------------------------------------- GetCSSStyleAttrIndex : returns the index of the current attribute type in the CSSStyleAttributes array return NULL if not found ----------------------------------------------------------------------*/ #ifdef __STDC__ char *GetCSSStyleAttrIndex (char *attrstr, int *index) #else char *GetCSSStyleAttrIndex (attrstr, index) char *attrstr; int *index; #endif { int i; #ifdef STYLE_DEBUG fprintf(stderr, " GetCSSStyleAttrIndex: enter [%s]\n", attrstr); #endif SKIP_BLANK (attrstr); for (i = 0; i < NB_CSSSTYLEATTRIBUTE; i++) if (IS_WORD (attrstr, CSSStyleAttributes[i].name)) { *index = i; #ifdef STYLE_DEBUG fprintf(stderr, " GetCSSStyleAttrIndex: leave\n"); #endif return (attrstr + strlen (CSSStyleAttributes[i].name)); } #ifdef STYLE_DEBUG fprintf(stderr, " GetCSSStyleAttrIndex: leave with NULL\n"); #endif return (NULL); } /************************************************************************ * * * MISC FUNCTIONS * * * ************************************************************************/ /*----------------------------------------------------------------------- GetTypeFromName : Sets the type and schema corresponding to the given element in the given schema. params : type : ptr on the type to set elSchema : ptr on the SSchema to set docSchema : SSchema where the element can be found name : string containing the name of the searched element. -----------------------------------------------------------------------*/ #ifdef __STDC__ void GetTypeFromName (int *type, SSchema *elSchema, SSchema docSchema, char *name) #else void GetTypeFromName (type, elSchema, docShema, name) int *type; SShema *elSchema; SShema docShema; char *name; #endif { ElementType elType; elType.ElSSchema = docSchema; TtaGiveTypeFromOriginalName(&elType, name); if (elType.ElTypeNum == 0) { elType.ElSSchema = docSchema; TtaGiveTypeFromName(&elType, name); } *type = elType.ElTypeNum; if (elSchema != NULL) *elSchema = elType.ElSSchema; } /*---------------------------------------------------------------------- SetHTMLStyleParserDestructiveMode : ----------------------------------------------------------------------*/ #ifdef __STDC__ void SetHTMLStyleParserDestructiveMode (boolean mode) #else void SetHTMLStyleParserDestructiveMode (mode) boolean mode; #endif { #ifdef DEBUG_CSS if (mode != HTMLStyleParserDestructiveMode) { if (mode) fprintf (stderr, "Switching HTML Style parser to destroy mode\n"); else fprintf (stderr, "Switching HTML Style back to normal mode\n"); } #endif HTMLStyleParserDestructiveMode = mode; }