Exemplo n.º 1
0
void
lo_ProcessSpacerTag(MWContext *context, lo_DocState *state, PA_Tag *tag)
{
	int32 type;
	int32 size;
	PA_Block buff;
	LO_SpacerStruct *spacer;
	
	spacer = (LO_SpacerStruct*)lo_NewElement(context, state, LO_SPACER, NULL, 0);
	XP_ASSERT(spacer);
	if (!spacer) 
	{
		state->top_state->out_of_memory = TRUE;
		return;
	}

	type = SPACE_WORD;
	buff = lo_FetchParamValue(context, tag, PARAM_TYPE);
	if (buff != NULL)
	{
		char *type_str;

		PA_LOCK(type_str, char *, buff);
		if (pa_TagEqual("line", type_str))
		{
			type = SPACE_LINE;
		}
		else if (pa_TagEqual("vert", type_str))
		{
			type = SPACE_LINE;
		}
		else if (pa_TagEqual("vertical", type_str))
		{
			type = SPACE_LINE;
		}
		else if (pa_TagEqual("block", type_str))
		{
			type = SPACE_BLOCK;
		}
		PA_UNLOCK(buff);
		PA_FREE(buff);
	}

	size = 0;
	buff = lo_FetchParamValue(context, tag, PARAM_SIZE);
	if (buff != NULL)
	{
		char *str;

		PA_LOCK(str, char *, buff);
		size = XP_ATOI(str);
		PA_UNLOCK(buff);
		PA_FREE(buff);
		if (size < 1)
		{
			size = 0;
		}
	}	

	spacer->size = size;
	spacer->type = (int8) type;
	spacer->tag = tag;

	lo_AppendSpacerElementToLineList( context, state, spacer );
	lo_LayoutSpacerElement(context, state, spacer, FALSE);

	/*
	 * Spacers of size 0 do nothing.
	 * Unless they are block spacers that use WIDTH and HEIGHT.
	 */
	/*
	if ((size == 0)&&(type != SPACE_BLOCK))
	{
		return;
	}

	if (type == SPACE_WORD)
	{
		lo_InsertWordBreak(context, state);
		size = FEUNITS_X(size, context);
		state->x += size;
	}
	else if (type == SPACE_LINE)
	{
		lo_SetSoftLineBreakState(context, state, FALSE, 1);
		size = FEUNITS_Y(size, context);
		state->y += size;
	}
	else if (type == SPACE_BLOCK)
	{
		lo_format_block_spacer(context, state, tag);
	}
	*/
}
Exemplo n.º 2
0
/*
 * This function parses a list of numbers (coordinates).
 * The numbers can have any integer value, and it is a comma separated list.
 * (optionally, whitespace can replace commas as separators in the list)
 */
int32 *
lo_parse_coord_list(char *str, int32 *value_cnt, Bool must_be_odd)
{
	char *tptr;
	char *n_str;
	int32 i, cnt, acnt;
	int32 *value_list;

	/*
	 * Nothing in an empty list
	 */
	*value_cnt = 0;
	if ((str == NULL)||(*str == '\0'))
	{
		return((int32 *)NULL);
	}

	/*
	 * Skip beginning whitespace, all whitespace is empty list.
	 */
	n_str = str;
	while (XP_IS_SPACE(*n_str))
	{
		n_str++;
	}
	if (*n_str == '\0')
	{
		return((int32 *)NULL);
	}

	/*
	 * Make a pass where any two numbers separated by just whitespace
	 * are given a comma separator.  Count entries while passing.
	 */
	cnt = 0;
	while (*n_str != '\0')
	{
		Bool has_comma;

		/*
		 * Skip to a separator
		 */
		tptr = n_str;
		while ((!XP_IS_SPACE(*tptr))&&(*tptr != ',')&&(*tptr != '\0'))
		{
			tptr++;
		}
		n_str = tptr;

		/*
		 * If no more entries, break out here
		 */
		if (*n_str == '\0')
		{
			break;
		}

		/*
		 * Skip to the end of the separator, noting if we have a
		 * comma.
		 */
		has_comma = FALSE;
		while ((XP_IS_SPACE(*tptr))||(*tptr == ','))
		{
			if (*tptr == ',')
			{
				if (has_comma == FALSE)
				{
					has_comma = TRUE;
				}
				else
				{
					break;
				}
			}
			tptr++;
		}
		/*
		 * If this was trailing whitespace we skipped, we are done.
		 */
		if ((*tptr == '\0')&&(has_comma == FALSE))
		{
			break;
		}
		/*
		 * Else if the separator is all whitespace, and this is not the
		 * end of the string, add a comma to the separator.
		 */
		else if (has_comma == FALSE)
		{
			*n_str = ',';
		}

		/*
		 * count the entry skipped.
		 */
		cnt++;

		n_str = tptr;
	}
	/*
	 * count the last entry in the list.
	 */
	cnt++;
	
	/*
	 * For polygons, we need a fake empty coord at the
	 * end of the list of x,y pairs.
	 */
	if ((must_be_odd != FALSE)&&((cnt & 0x01) == 0))
	{
		acnt = cnt + 1;
	}
	else
	{
		acnt = cnt;
	}

	*value_cnt = acnt;

	/*
	 * Allocate space for the coordinate array.
	 */
	value_list = (int32 *)XP_ALLOC(acnt * sizeof(int32));
	if (value_list == NULL)
	{
		return((int32 *)NULL);
	}

	/*
	 * Second pass to copy integer values into list.
	 */
	tptr = str;
	for (i=0; i<cnt; i++)
	{
		char *ptr;

		ptr = strchr(tptr, ',');
		if (ptr != NULL)
		{
			*ptr = '\0';
		}
		/*
		 * Strip whitespace in front of number because I don't
		 * trust atoi to do it on all platforms.
		 */
		while (XP_IS_SPACE(*tptr))
		{
			tptr++;
		}
		if (*tptr == '\0')
		{
			value_list[i] = 0;
		}
		else
		{
			value_list[i] = (int32)XP_ATOI(tptr);
		}
		if (ptr != NULL)
		{
			*ptr = ',';
			tptr = (char *)(ptr + 1);
		}
	}
	return(value_list);
}
Exemplo n.º 3
0
/* parse lines in an HTML help mapping file.
 * get window_size and name, etc...
 *
 * when the id is found function returns HTML_HELP_ID_FOUND
 * on error function returns negative error code.
 */
PRIVATE int
net_ParseHTMLHelpLine(HTMLHelpParseObj *obj, char *line_data)
{
	char *line = XP_StripLine(line_data);
	char *token;
	char *next_word;

	if(*line == '<')
	  {
		/* find and terminate the end '>' */
		XP_STRTOK(line, ">");

		token = XP_StripLine(line+1);

		if(!strncasecomp(token, 
						 ID_MAP_TOKEN, 
						 sizeof(ID_MAP_TOKEN)-1))
		  {
			obj->in_id_mapping = TRUE;
		  }
		else if(!strncasecomp(token, 
						 END_ID_MAP_TOKEN, 
						 sizeof(END_ID_MAP_TOKEN)-1))
		  {
			obj->in_id_mapping = FALSE;
		  }
		else if(!strncasecomp(token, 
						 FRAME_GROUP_TOKEN, 
						 sizeof(FRAME_GROUP_TOKEN)-1))
		  {
			char *cp = token + sizeof(FRAME_GROUP_TOKEN)-1;
			frame_set_struct * fgs = XP_NEW(frame_set_struct);

			while(isspace(*cp)) cp++;

			if(fgs)
			  {
				XP_MEMSET(fgs, 0, sizeof(frame_set_struct));

				next_word=NULL; /* init */

				do {
					if(!strncasecomp(cp, SRC_TOKEN, sizeof(SRC_TOKEN)-1))
				  	  {
						char *address = net_get_html_help_token(
														cp+sizeof(SRC_TOKEN)-1,
														&next_word);
						cp = next_word;
						fgs->address = XP_STRDUP(address);
				  	  }
					else if(!strncasecomp(cp, 
									  WINDOW_TOKEN, 
									  sizeof(WINDOW_TOKEN)-1))
				      {
					    char *window = net_get_html_help_token(
													cp+sizeof(WINDOW_TOKEN)-1, 
													&next_word);
					    cp = next_word;
					    fgs->target = XP_STRDUP(window);
				      }
					else
					  {
						/* unknown attribute.  Skip to next whitespace
						 */ 
						while(*cp && !isspace(*cp)) 
							cp++;


						if(*cp)
						  {
							while(isspace(*cp)) cp++;
							next_word = cp;
						  }
						else
						  {
							next_word = NULL;
						  }
					  }

				  } while(next_word);
			
				XP_ListAddObject(obj->frame_group_stack, fgs);
			  }
		  }
		else if(!strncasecomp(token, 
						 END_FRAME_GROUP_TOKEN, 
						 sizeof(END_FRAME_GROUP_TOKEN)-1))
		  {
			frame_set_struct *fgs;

			fgs = XP_ListRemoveTopObject(obj->frame_group_stack);

			if(fgs)
				net_help_free_frame_group_struct(fgs);
		  }
	  }
	else if(!obj->in_id_mapping)
	  {
		if(!strncasecomp(line, 
					 	WINDOW_SIZE_TOKEN, 
					 	sizeof(WINDOW_SIZE_TOKEN)-1))
		  {
			/* get window size */
			char *comma=0;
			char *window_size = net_get_html_help_token(line+
												sizeof(WINDOW_SIZE_TOKEN)-1, 
												NULL);

			if(window_size)
				comma = XP_STRCHR(window_size, ',');

			if(comma)
			  {
				*comma =  '\0';
				obj->window_width = XP_ATOI(window_size);
				obj->window_height = XP_ATOI(comma+1);
			  }
		  }
		else if(!strncasecomp(line, 
						 	WINDOW_NAME_TOKEN, 
						 	sizeof(WINDOW_NAME_TOKEN)-1))
		  {
			char *window_name = net_get_html_help_token(line+
												sizeof(WINDOW_NAME_TOKEN)-1,
												NULL);

			if(window_name)
			  {
				FREEIF(obj->window_name);
				obj->window_name = XP_STRDUP(window_name);
			  }
		  }
		else if(!strncasecomp(line, 
					 	HELP_VERSION_TOKEN, 
					 	sizeof(HELP_VERSION_TOKEN)-1))
		  {
			/* get window size */
			char *help_version = net_get_html_help_token(line+
												sizeof(HELP_VERSION_TOKEN)-1, 
												NULL);

			if(help_version)
			  {
				obj->helpVersion = XP_ATOI(help_version);
			  }
		  }
	  }
	else
	  {
		/* id mapping pair */
		if(!strncasecomp(line, obj->id, XP_STRLEN(obj->id)))
		  {
			char *id_value = net_get_html_help_token(line+XP_STRLEN(obj->id),
													 &next_word);

			if(id_value)
			  {
			  	obj->id_value = XP_STRDUP(id_value);

				while(next_word)
				  {
					char *cp = next_word;

                    if(!strncasecomp(cp,
                                     TARGET_TOKEN,
                                      sizeof(TARGET_TOKEN)-1))
                      {
                        char *target = net_get_html_help_token(
                                                    cp+sizeof(TARGET_TOKEN)-1,
                                                    &next_word);
                        cp = next_word;
                        obj->content_target = XP_STRDUP(target);
                      }
					else
					  {
                        /* unknown attribute.  Skip to next whitespace
                         */
                        while(*cp && !isspace(*cp))
                            cp++;

                        if(*cp)
                          {
                            while(isspace(*cp)) cp++;
                            next_word = cp;
                          }
                        else
                          {
                            next_word = NULL;
                          }
					  }
				  }
			  }
		
			return(HTML_HELP_ID_FOUND);
		  }
		if(!strncasecomp(line, DEFAULT_HELP_ID, sizeof(DEFAULT_HELP_ID)-1))
		  {
			char *default_id_value = net_get_html_help_token(
												line+sizeof(DEFAULT_HELP_ID)-1,
												NULL);

            if(default_id_value)
                obj->default_id_value = XP_STRDUP(default_id_value);
		  }
		
	  }

	return(0);
}
Exemplo n.º 4
0
static void
lo_FormatJavaAppInternal(MWContext *context, lo_DocState *state, PA_Tag *tag, LO_JavaAppStruct *java_app)
{
	PA_Block buff;
	char *str;
	int32 val;
	int32 doc_width;
	Bool widthSpecified = FALSE;
	Bool heightSpecified = FALSE;
	lo_DocLists *doc_lists;

    java_app->nextApplet = NULL;
#ifdef MOCHA
    java_app->mocha_object = NULL;
#endif

	java_app->FE_Data = NULL;
	java_app->session_data = NULL;
	java_app->line_height = state->line_height;

	java_app->base_url = NULL;
	java_app->attr_code = NULL;
	java_app->attr_codebase = NULL;
	java_app->attr_archive = NULL;
	java_app->attr_name = NULL;

	java_app->param_cnt = 0;
	java_app->param_names = NULL;
	java_app->param_values = NULL;

	java_app->may_script = FALSE;

	java_app->alignment = LO_ALIGN_BASELINE;
	java_app->border_width = JAVA_DEF_BORDER;
	java_app->border_vert_space = JAVA_DEF_VERTICAL_SPACE;
	java_app->border_horiz_space = JAVA_DEF_HORIZONTAL_SPACE;
	
	java_app->layer = NULL;
	java_app->tag = tag;

	/*
	 * Assign a unique index for this object 
	 * and increment the master index.
	 */
	java_app->embed_index = state->top_state->embed_count++;

	/*
	 * Save away the base of the document
	 */
	buff = PA_ALLOC(XP_STRLEN(state->top_state->base_url) + 1);
	if (buff != NULL)
	{
		char *cp;
		PA_LOCK(cp, char*, buff);
		XP_STRCPY(cp, state->top_state->base_url);
		PA_UNLOCK(buff);
		java_app->base_url = buff;
	}
	else
	{
		state->top_state->out_of_memory = TRUE;
		return;
	}

	/*
	 * Check for an align parameter
	 */
	buff = lo_FetchParamValue(context, tag, PARAM_ALIGN);
	if (buff != NULL)
	{
		Bool floating;

		floating = FALSE;
		PA_LOCK(str, char *, buff);
		java_app->alignment = lo_EvalAlignParam(str, &floating);
		if (floating != FALSE)
		{
			java_app->ele_attrmask |= LO_ELE_FLOATING;
		}
		PA_UNLOCK(buff);
		PA_FREE(buff);
	}

	/*
	 * Get the applet CODE or object CLASSID parameter. In both
	 * cases the value is place in java_app->attr_code
	 */
	if (java_app->selector_type == LO_JAVA_SELECTOR_APPLET)
	{
		/* APPLET tag CODE attribute */

		buff = lo_FetchParamValue(context, tag, PARAM_CODE);
	}
	else
	{
		/* OBJECT tag CLASSID attribute */

		char * str1, * str2;
		PA_Block new_buff;

		int selectorLength;

		selectorLength = 5;
		if (java_app->selector_type == LO_JAVA_SELECTOR_OBJECT_JAVAPROGRAM)
			selectorLength = 12;
		else if (java_app->selector_type == LO_JAVA_SELECTOR_OBJECT_JAVABEAN)
			selectorLength = 9;

		buff = lo_FetchParamValue(context, tag, PARAM_CLASSID);

		if (buff != NULL)
		{
			/* remove the "java:", "javaprogram:", or "javabean:"
			 * protocol selector.
			 */
			PA_LOCK(str1, char *, buff);
			new_buff = PA_ALLOC(XP_STRLEN(str1) + 1);
			PA_LOCK(str2, char *, new_buff);
			XP_STRCPY(str2, str1 + selectorLength);
			PA_UNLOCK(new_buff);
			PA_UNLOCK(buff);
			PA_FREE(buff);
			buff = new_buff;
		}
	}
	java_app->attr_code = buff;

	/*
	 * Check for the loaderbase parameter.
	 */
	buff = lo_FetchParamValue(context, tag, PARAM_CODEBASE);
	java_app->attr_codebase = buff;

	/*
	 * Check for the archive parameter.
	 */
	buff = lo_FetchParamValue(context, tag, PARAM_ARCHIVE);
	java_app->attr_archive = buff;

	/*
	 * Check for a mayscript attribute
	 */
	buff = lo_FetchParamValue(context, tag, PARAM_MAYSCRIPT);
	if (buff != NULL)
	{
		java_app->may_script = TRUE;
		PA_FREE(buff);
	}

	/*
	 * Get the name of this java applet.
	 */
	if (java_app->selector_type != LO_JAVA_SELECTOR_APPLET)
		buff = lo_FetchParamValue(context, tag, PARAM_ID);
	else
		buff = lo_FetchParamValue(context, tag, PARAM_NAME);
	if (buff != NULL)
	{
		PA_LOCK(str, char *, buff);
		if (str != NULL)
		{
			int32 len;

			len = lo_StripTextWhitespace(str, XP_STRLEN(str));
		}
		PA_UNLOCK(buff);
	}
	java_app->attr_name = buff;

	doc_width = state->right_margin - state->left_margin;

	/*
	 * Get the width parameter, in absolute or percentage.
	 * If percentage, make it absolute.
	 */
	buff = lo_FetchParamValue(context, tag, PARAM_WIDTH);
	if (buff != NULL)
	{
		Bool is_percent;

		PA_LOCK(str, char *, buff);
		val = lo_ValueOrPercent(str, &is_percent);
		if (is_percent != FALSE)
		{
			java_app->percent_width = val;
		}
		else
		{
			java_app->percent_width = 0;
			java_app->width = val;
			val = FEUNITS_X(val, context);
		}
		PA_UNLOCK(buff);
		PA_FREE(buff);
		widthSpecified = TRUE;
	}
	val = LO_GetWidthFromStyleSheet(context, state);
	if(val)
	{
		java_app->width = val;
		widthSpecified = TRUE;
	}

	/*
	 * Get the height parameter, in absolute or percentage.
	 * If percentage, make it absolute.
	 */
	buff = lo_FetchParamValue(context, tag, PARAM_HEIGHT);
	if (buff != NULL)
	{
		Bool is_percent;

		PA_LOCK(str, char *, buff);
		val = lo_ValueOrPercent(str, &is_percent);
		if (is_percent != FALSE)
		{
			java_app->percent_height = val;
		}
		else
		{
			java_app->percent_height = 0;
			val = FEUNITS_Y(val, context);
		}
		java_app->height = val;
		PA_UNLOCK(buff);
		PA_FREE(buff);
		heightSpecified = TRUE;
	}

	val = LO_GetHeightFromStyleSheet(context, state);
	if(val)
	{
		java_app->height = val;
		heightSpecified = TRUE;
	}

	/* If they forgot to specify a width, make one up. */
	if (!widthSpecified) {
		val = 0;
		if (heightSpecified) {
			val = java_app->height;
		}
		else if (state->allow_percent_width) {
			val = state->win_width * 90 / 100;
		}
		if (val < 1) {
			val = 600;
		}
		java_app->width = val;
	}
	
	/* If they forgot to specify a height, make one up. */
	if (!heightSpecified) {
		val = 0;
		if (widthSpecified) {
			val = java_app->width;
		}
		else if (state->allow_percent_height) {
			val = state->win_height / 2;
		}
		if (val < 1) {
			val = 400;
		}
		java_app->height = val;
	}

    /* After going through all the trouble, just to make sure
     * the object tag HIDDEN case is covered as well.
     */
    if (java_app->ele_attrmask & LO_ELE_HIDDEN)
    {
        java_app->width = 0;
        java_app->height = 0;
    }

	/*
	 * Get the border parameter.
	 */
	buff = lo_FetchParamValue(context, tag, PARAM_BORDER);
	if (buff != NULL)
	{
		PA_LOCK(str, char *, buff);
		val = XP_ATOI(str);
		if (val < 0)
		{
			val = 0;
		}
		java_app->border_width = val;
		PA_UNLOCK(buff);
		PA_FREE(buff);
	}
	java_app->border_width = FEUNITS_X(java_app->border_width, context);

	/*
	 * Get the extra vertical space parameter.
	 */
	buff = lo_FetchParamValue(context, tag, PARAM_VSPACE);
	if (buff != NULL)
	{
		PA_LOCK(str, char *, buff);
		val = XP_ATOI(str);
		if (val < 0)
		{
			val = 0;
		}
		java_app->border_vert_space = val;
		PA_UNLOCK(buff);
		PA_FREE(buff);
	}
	java_app->border_vert_space = FEUNITS_Y(java_app->border_vert_space,
							context);

	/*
	 * Get the extra horizontal space parameter.
	 */
	buff = lo_FetchParamValue(context, tag, PARAM_HSPACE);
	if (buff != NULL)
	{
		PA_LOCK(str, char *, buff);
		val = XP_ATOI(str);
		if (val < 0)
		{
			val = 0;
		}
		java_app->border_horiz_space = val;
		PA_UNLOCK(buff);
		PA_FREE(buff);
	}
	java_app->border_horiz_space = FEUNITS_X(java_app->border_horiz_space,
						context);

	lo_FillInJavaAppGeometry(state, java_app, FALSE);

	/*
	 * See if we have some saved embed/java_app session data to restore.
	 */
	if (state->top_state->savedData.EmbedList != NULL)
	{
		lo_SavedEmbedListData *embed_list;
		embed_list = state->top_state->savedData.EmbedList;

		/*
		 * If there is still valid data to restore available.
		 */
		if (java_app->embed_index < embed_list->embed_count)
		{
			lo_EmbedDataElement* embed_data_list;

			PA_LOCK(embed_data_list, lo_EmbedDataElement*,
				embed_list->embed_data_list);
			java_app->session_data =
				embed_data_list[java_app->embed_index].data;
			PA_UNLOCK(embed_list->embed_data_list);
		}
Exemplo n.º 5
0
void
lo_BeginMulticolumn(MWContext *context, lo_DocState *state, PA_Tag *tag, LO_MulticolumnStruct *multicolEle)
{
	lo_MultiCol *multicol;
	PA_Block buff;
	char *str;
	int32 val;
	int32 doc_width;
	/* int32 width; */

	multicol = XP_NEW(lo_MultiCol);
	if (multicol == NULL)
	{
		state->top_state->out_of_memory = TRUE;
		return;
	}

	multicol->width = 0;
	multicol->isPercentWidth = FALSE;	

	/* Put a pointer to lo_multicol inside the MULTICOLUMN layout element that will be placed on the
	   line list */
	multicolEle->multicol = multicol;
    
	/*
     * If this multicol is within a layer, then we have to create an
     * artificial TABLE around it (since the multicol code depends on
     * the state's line array, which isn't in an updated state within
     * a layer). 
     */
    if (state->layer_nest_level > 0)
    {
        PA_Tag *tmp_tag;
        lo_TableRec *table;

        if (state->in_paragraph != FALSE)
        {
            lo_CloseParagraph(context, &state, tag, 2);
        }

        lo_BeginTableAttributes(context, state, NULL, NULL, NULL, NULL,
                                NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                                NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                                NULL, NULL, NULL);
        
        table = state->current_table;
        if (table) {
            lo_BeginTableRowAttributes(context, state, table,
                                       NULL, NULL, NULL, NULL);

            lo_BeginTableCellAttributes(context, state, table,
                                        NULL, NULL, NULL, NULL, NULL,
                                        LO_TILE_BOTH, NULL, NULL, NULL, NULL,
                                        FALSE, TRUE);

            /* 
             * If we've successfully created a subdoc, we need to clone
             * the MULTICOL tag and save it in the subdoc, since the code
             * above us doesn't realize we're now in a table.
             */
            if (state->sub_state) {
                state = state->sub_state;
                tmp_tag = PA_CloneMDLTag(tag);
                lo_SaveSubdocTags(context, state, tmp_tag);
            }
            multicol->close_table = TRUE;
        }
    }
    else {		
		/* if (line will not be flushed by lo_SetSoftLineBreak) and (there exist some elements on the line list) */
		if (state->linefeed_state >= 2 && state->line_list != NULL)
		{
			/* Append zero width and height line feed to the line list and flush the line list into
			   the line array. This forces the layout of elements contained within the MULTICOL tags
			   to start on a blank line_list and hence on a new line.  lo_EndMultiColumn needs this to
			   do its line array hacking properly. */
			lo_AppendZeroWidthAndHeightLF(context, state);			
		}

		lo_SetSoftLineBreakState(context, state, FALSE, 2);
        multicol->close_table = FALSE;		
    }

	/*
	 * Since we are going to block layout during multicol
	 * processing, we need to flush the compositor of any
	 * pending displays.
	 */
	if (context->compositor)
	{
		CL_CompositeNow(context->compositor);
	}

	lo_StartMultiColInit( state, multicol );

	/*
	multicol->end_last_line = state->end_last_line;
	multicol->start_ele = state->top_state->element_id;
	multicol->start_line = state->line_num;
	multicol->end_line = multicol->start_line;
	multicol->start_x = state->x;
	multicol->start_y = state->y;
	multicol->end_y = multicol->start_y;
	*/
	multicol->cols = 1;
	multicol->gutter = MULTICOL_GUTTER_WIDTH;

	/*	
     * Get the cols parameter.
     */
    buff = lo_FetchParamValue(context, tag, PARAM_COLS);
    if (buff != NULL)
    {
		PA_LOCK(str, char *, buff);
		multicol->cols = XP_ATOI(str);
		PA_UNLOCK(buff);
		PA_FREE(buff);
	}

	if (multicol->cols <= 1)
	{
		XP_DELETE(multicol);
		multicolEle->multicol = NULL;
		return;
	}

	/*
     * Get the gutter parameter.
     */
    buff = lo_FetchParamValue(context, tag, PARAM_GUTTER);
    if (buff != NULL)
    {
        PA_LOCK(str, char *, buff);
		multicol->gutter = XP_ATOI(str);
		if (multicol->gutter < 1)
		{
			multicol->gutter = 1;
		}
		PA_UNLOCK(buff);
		PA_FREE(buff);
	}

	multicol->gutter = FEUNITS_X(multicol->gutter, context);

	doc_width = state->right_margin - state->left_margin;
	/* width = doc_width; */

	/*
	 * Get the width parameter, in absolute or percentage.
	 * If percentage, make it absolute.
	 */
	/*
	buff = lo_FetchParamValue(context, tag, PARAM_WIDTH);
	if (buff != NULL)
	{
		Bool is_percent;

		PA_LOCK(str, char *, buff);
		val = lo_ValueOrPercent(str, &is_percent);
		if (is_percent != FALSE)
		{
			if (state->allow_percent_width == FALSE)
			{
				val = 0;
			}
			else
			{
				val = doc_width * val / 100;
				if (val < 1)
				{
					val = 1;
				}
			}
		}
		else
		{
			val = FEUNITS_X(val, context);
			if (val < 1)
			{
				val = 1;
			}
		}
		width = val;
		PA_UNLOCK(buff);
		PA_FREE(buff);
	}
	*/

	buff = lo_FetchParamValue(context, tag, PARAM_WIDTH);
	if (buff != NULL)
	{
		Bool is_percent;

		PA_LOCK(str, char *, buff);
		val = lo_ValueOrPercent(str, &is_percent);
		if (is_percent != FALSE)
		{
			multicol->width = val;
			multicol->isPercentWidth = TRUE;
		}
		else
		{
			multicol->width = val;
			multicol->isPercentWidth = FALSE;
			val = FEUNITS_X(val, context);
			if (val < 1)
			{
				val = 1;
			}
		}
		PA_UNLOCK(buff);
		PA_FREE(buff);
	}

	/*
	width = width - ((multicol->cols - 1) * multicol->gutter);
	multicol->col_width = width / multicol->cols;
	if (multicol->col_width < MULTICOL_MIN_WIDTH)
	{
		multicol->col_width = MULTICOL_MIN_WIDTH;
	}

	multicol->orig_margin = state->right_margin;

	lo_PushList(state, tag, QUOTE_NONE);
*/

	lo_SetupStateForBeginMulticol( state, multicol, doc_width );
	
	/*
	state->right_margin = state->left_margin + multicol->col_width;
	state->x = state->left_margin;
	state->list_stack->old_left_margin = state->left_margin;
	state->list_stack->old_right_margin = state->right_margin;

	multicol->orig_min_width = state->min_width;
	state->min_width = 0;
	*/

	/*
	 * Don't display anything while processing the multicolumn text.
	 */
	/*
	multicol->orig_display_blocking_element_y = state->display_blocking_element_y;
	state->display_blocking_element_y = -1;
	multicol->orig_display_blocked = state->display_blocked;
	state->display_blocked = TRUE;

	multicol->next = state->current_multicol;
	state->current_multicol = multicol;
	*/
}