зеркало из https://github.com/mozilla/gecko-dev.git
809 строки
16 KiB
C
809 строки
16 KiB
C
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
*
|
|
* The contents of this file are subject to the Netscape Public License
|
|
* Version 1.0 (the "NPL"); you may not use this file except in
|
|
* compliance with the NPL. You may obtain a copy of the NPL at
|
|
* http://www.mozilla.org/NPL/
|
|
*
|
|
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
|
* for the specific language governing rights and limitations under the
|
|
* NPL.
|
|
*
|
|
* The Initial Developer of this code under the NPL is Netscape
|
|
* Communications Corporation. Portions created by Netscape are
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
|
* Reserved.
|
|
*/
|
|
|
|
|
|
#include "xp.h"
|
|
#include "pa_parse.h"
|
|
#include "layout.h"
|
|
|
|
|
|
#define SPACE_WORD 1
|
|
#define SPACE_LINE 2
|
|
#define SPACE_BLOCK 3
|
|
|
|
static void lo_AppendSpacerElementToLineList( MWContext *context, lo_DocState *state,
|
|
LO_SpacerStruct *spacer );
|
|
static void lo_ParseAttributesForBlockSpacer( MWContext *context, lo_DocState *state,
|
|
LO_SpacerStruct *spacer );
|
|
static void lo_LayoutBlockSpacer(MWContext *context, lo_DocState *state,
|
|
LO_SpacerStruct *spacer, Bool relayout);
|
|
|
|
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);
|
|
}
|
|
*/
|
|
}
|
|
|
|
static void lo_AppendSpacerElementToLineList( MWContext *context, lo_DocState *state, LO_SpacerStruct *spacer )
|
|
{
|
|
spacer->lo_any.type = LO_SPACER;
|
|
spacer->lo_any.x = state->x;
|
|
spacer->lo_any.y = state->y;
|
|
spacer->lo_any.x_offset = 0;
|
|
spacer->lo_any.y_offset = 0;
|
|
spacer->lo_any.width = 0;
|
|
spacer->lo_any.height = 0;
|
|
spacer->lo_any.line_height = 0;
|
|
spacer->lo_any.ele_id = NEXT_ELEMENT;
|
|
|
|
lo_AppendToLineList(context, state, (LO_Element*)spacer, 0);
|
|
}
|
|
|
|
|
|
void lo_LayoutSpacerElement(MWContext *context, lo_DocState *state, LO_SpacerStruct *spacer, Bool relayout)
|
|
{
|
|
int32 size = spacer->size;
|
|
int8 type = spacer->type;
|
|
|
|
/*
|
|
* 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)
|
|
{
|
|
if (!relayout)
|
|
lo_InsertWordBreak(context, state);
|
|
|
|
size = FEUNITS_X(size, context);
|
|
state->x += size;
|
|
}
|
|
else if (type == SPACE_LINE)
|
|
{
|
|
/* lo_SetSoftLineBreakState(context, state, FALSE, 1); */
|
|
lo_SetLineBreakState(context, state, FALSE, LO_LINEFEED_BREAK_SOFT, 1, relayout);
|
|
size = FEUNITS_Y(size, context);
|
|
state->y += size;
|
|
}
|
|
else if (type == SPACE_BLOCK)
|
|
{
|
|
if (!relayout)
|
|
{
|
|
lo_ParseAttributesForBlockSpacer(context, state, spacer);
|
|
}
|
|
|
|
lo_LayoutBlockSpacer(context, state, spacer, relayout);
|
|
}
|
|
|
|
if (!relayout)
|
|
{
|
|
/* We do not want to keep a pointer to the tag around for relayout
|
|
because we have all the information we need in the LO_SPACER
|
|
layout element */
|
|
spacer->tag = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
static void lo_ParseAttributesForBlockSpacer( MWContext *context, lo_DocState *state, LO_SpacerStruct *spacer )
|
|
{
|
|
Bool floating;
|
|
int32 alignment;
|
|
int32 val;
|
|
PA_Block buff;
|
|
PA_Tag *tag = spacer->tag;
|
|
char *str;
|
|
|
|
alignment = LO_ALIGN_BASELINE;
|
|
floating = FALSE;
|
|
|
|
/*
|
|
* Check for an align parameter
|
|
*/
|
|
buff = lo_FetchParamValue(context, tag, PARAM_ALIGN);
|
|
if (buff != NULL)
|
|
{
|
|
PA_LOCK(str, char *, buff);
|
|
alignment = lo_EvalAlignParam(str, &floating);
|
|
PA_UNLOCK(buff);
|
|
PA_FREE(buff);
|
|
}
|
|
spacer->alignment = alignment;
|
|
spacer->floating = floating;
|
|
|
|
/*
|
|
* 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)
|
|
{
|
|
spacer->is_percent_width = TRUE;
|
|
spacer->width = val;
|
|
}
|
|
else
|
|
{
|
|
spacer->is_percent_width = FALSE;
|
|
val = FEUNITS_X(val, context);
|
|
if (val < 1)
|
|
{
|
|
val = 1;
|
|
}
|
|
spacer->width = val;
|
|
}
|
|
PA_UNLOCK(buff);
|
|
PA_FREE(buff);
|
|
}
|
|
|
|
/*
|
|
* 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)
|
|
{
|
|
spacer->is_percent_height = TRUE;
|
|
spacer->height = val;
|
|
}
|
|
else
|
|
{
|
|
spacer->is_percent_height = FALSE;
|
|
val = FEUNITS_Y(val, context);
|
|
if (val < 1)
|
|
{
|
|
val = 1;
|
|
}
|
|
spacer->height = val;
|
|
}
|
|
PA_UNLOCK(buff);
|
|
PA_FREE(buff);
|
|
}
|
|
}
|
|
|
|
static void lo_LayoutBlockSpacer(MWContext *context, lo_DocState *state, LO_SpacerStruct *spacer, Bool relayout)
|
|
{
|
|
int32 width = 0;
|
|
int32 height = 0;
|
|
int32 doc_width;
|
|
int32 alignment = spacer->alignment;
|
|
Bool floating = spacer->floating;
|
|
Bool line_break;
|
|
char *str;
|
|
int32 x, y;
|
|
int16 x_offset;
|
|
int32 y_offset;
|
|
int32 baseline_inc, line_inc;
|
|
LO_TextStruct tmp_text;
|
|
LO_TextInfo text_info;
|
|
LO_Element *eptr;
|
|
PA_Block buff;
|
|
|
|
x = state->x;
|
|
y = state->y;
|
|
doc_width = state->right_margin - state->left_margin;
|
|
|
|
if (spacer->is_percent_width)
|
|
{
|
|
int32 val;
|
|
|
|
if (state->allow_percent_width == FALSE)
|
|
{
|
|
val = 0;
|
|
}
|
|
else
|
|
{
|
|
val = spacer->width;
|
|
val = doc_width * val / 100;
|
|
if (val < 1)
|
|
{
|
|
val = 1;
|
|
}
|
|
}
|
|
|
|
width = val;
|
|
}
|
|
else
|
|
{
|
|
width = spacer->width;
|
|
}
|
|
|
|
if (spacer->is_percent_height)
|
|
{
|
|
int32 val;
|
|
|
|
if (state->allow_percent_height == FALSE)
|
|
{
|
|
val = 0;
|
|
}
|
|
else
|
|
{
|
|
val = spacer->height;
|
|
val = state->win_height * val / 100;
|
|
if (val < 1)
|
|
{
|
|
val = 1;
|
|
}
|
|
}
|
|
height = val;
|
|
}
|
|
else
|
|
{
|
|
height = spacer->height;
|
|
}
|
|
|
|
|
|
/*
|
|
* All this work is to get the text_info filled in for the current
|
|
* font in the font stack. Yuck, there must be a better way.
|
|
*/
|
|
memset (&tmp_text, 0, sizeof (tmp_text));
|
|
buff = PA_ALLOC(1);
|
|
if (buff == NULL)
|
|
{
|
|
state->top_state->out_of_memory = TRUE;
|
|
return;
|
|
}
|
|
PA_LOCK(str, char *, buff);
|
|
str[0] = ' ';
|
|
PA_UNLOCK(buff);
|
|
tmp_text.text = buff;
|
|
tmp_text.text_len = 1;
|
|
#ifdef DOM
|
|
tmp_text.text_attr = lo_GetCurrentTextAttr(state, context);
|
|
#else
|
|
tmp_text.text_attr = state->font_stack->text_attr;
|
|
#endif
|
|
FE_GetTextInfo(context, &tmp_text, &text_info);
|
|
PA_FREE(buff);
|
|
|
|
/*
|
|
* If both dimentions are bogus, no spacer.
|
|
* If only one dimension bogus, then make it 1.
|
|
*/
|
|
if ((width < 1)&&(height < 1))
|
|
{
|
|
return;
|
|
}
|
|
else if (width < 1)
|
|
{
|
|
width = 1;
|
|
}
|
|
else if (height < 1)
|
|
{
|
|
height = 1;
|
|
}
|
|
|
|
|
|
/*
|
|
* SEVERE FLOW BREAK! This may be a floating image,
|
|
* which means at this point we go do something completely
|
|
* different.
|
|
*/
|
|
if (floating != FALSE)
|
|
{
|
|
if (alignment == LO_ALIGN_RIGHT)
|
|
{
|
|
if (state->right_margin_stack == NULL)
|
|
{
|
|
x = state->right_margin - width;
|
|
}
|
|
else
|
|
{
|
|
x = state->right_margin_stack->margin - width;
|
|
}
|
|
if (x < 0)
|
|
{
|
|
x = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
x = state->left_margin;
|
|
}
|
|
|
|
y = -1;
|
|
|
|
lo_AddMarginStack(state, x, y,
|
|
width, height, 0, 0, 0, alignment);
|
|
|
|
if (state->at_begin_line != FALSE)
|
|
{
|
|
lo_FindLineMargins(context, state, !relayout);
|
|
state->x = state->left_margin;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* Will this spacer make the line too wide.
|
|
*/
|
|
if ((state->x + width) > state->right_margin)
|
|
{
|
|
line_break = TRUE;
|
|
}
|
|
else
|
|
{
|
|
line_break = FALSE;
|
|
}
|
|
|
|
/*
|
|
* if we are at the beginning of the line. There is
|
|
* no point in breaking, we are just too wide.
|
|
* Also don't break in unmapped preformatted text.
|
|
* Also can't break inside a NOBR section.
|
|
*/
|
|
if ((state->at_begin_line != FALSE)||
|
|
(state->preformatted == PRE_TEXT_YES)||
|
|
(state->breakable == FALSE))
|
|
{
|
|
line_break = FALSE;
|
|
}
|
|
|
|
/*
|
|
* break on the spacer if we have
|
|
* a break.
|
|
*/
|
|
if (line_break != FALSE)
|
|
{
|
|
if (!relayout)
|
|
lo_SoftLineBreak(context, state, TRUE);
|
|
else
|
|
lo_rl_AddSoftBreakAndFlushLine(context, state);
|
|
|
|
x = state->x;
|
|
y = state->y;
|
|
}
|
|
|
|
/*
|
|
* Figure out how to align this spacer.
|
|
* baseline_inc is how much to increase the baseline
|
|
* of previous element of this line. line_inc is how
|
|
* much to increase the line height below the baseline.
|
|
*/
|
|
baseline_inc = 0;
|
|
line_inc = 0;
|
|
x_offset = 0;
|
|
y_offset = 0;
|
|
|
|
lo_CalcAlignOffsets(state, &text_info, alignment,
|
|
width, height,
|
|
&x_offset, &y_offset, &line_inc, &baseline_inc);
|
|
|
|
width += x_offset;
|
|
height += y_offset;
|
|
|
|
/*
|
|
* Change the rest of the line the way lo_AppendToLineList()
|
|
* would if we were adding a real element.
|
|
*/
|
|
eptr = state->line_list;
|
|
if (eptr != NULL)
|
|
{
|
|
while (eptr->lo_any.next != NULL)
|
|
{
|
|
eptr->lo_any.y_offset += baseline_inc;
|
|
eptr = eptr->lo_any.next;
|
|
}
|
|
eptr->lo_any.y_offset += baseline_inc;
|
|
}
|
|
|
|
state->baseline += (intn) baseline_inc;
|
|
state->line_height += (intn) (baseline_inc + line_inc);
|
|
|
|
/*
|
|
* Clean up state
|
|
*/
|
|
state->x = state->x + width;
|
|
state->linefeed_state = 0;
|
|
state->at_begin_line = FALSE;
|
|
state->trailing_space = FALSE;
|
|
state->cur_ele_type = LO_NONE;
|
|
}
|
|
|
|
#if 0
|
|
void
|
|
lo_format_block_spacer(MWContext *context, lo_DocState *state, PA_Tag *tag, Bool relayout)
|
|
{
|
|
Bool line_break;
|
|
Bool floating;
|
|
int32 baseline_inc, line_inc;
|
|
int32 alignment;
|
|
int16 x_offset;
|
|
int32 y_offset;
|
|
int32 x, y;
|
|
int32 width, height;
|
|
int32 doc_width;
|
|
int32 val;
|
|
PA_Block buff;
|
|
char *str;
|
|
LO_TextStruct tmp_text;
|
|
LO_TextInfo text_info;
|
|
LO_Element *eptr;
|
|
|
|
x = state->x;
|
|
y = state->y;
|
|
width = 0;
|
|
height = 0;
|
|
alignment = LO_ALIGN_BASELINE;
|
|
floating = FALSE;
|
|
|
|
/*
|
|
* Check for an align parameter
|
|
*/
|
|
buff = lo_FetchParamValue(context, tag, PARAM_ALIGN);
|
|
if (buff != NULL)
|
|
{
|
|
|
|
PA_LOCK(str, char *, buff);
|
|
alignment = lo_EvalAlignParam(str, &floating);
|
|
PA_UNLOCK(buff);
|
|
PA_FREE(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)
|
|
{
|
|
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);
|
|
}
|
|
|
|
/*
|
|
* 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)
|
|
{
|
|
if (state->allow_percent_height == FALSE)
|
|
{
|
|
val = 0;
|
|
}
|
|
else
|
|
{
|
|
val = state->win_height * val / 100;
|
|
if (val < 1)
|
|
{
|
|
val = 1;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
val = FEUNITS_Y(val, context);
|
|
if (val < 1)
|
|
{
|
|
val = 1;
|
|
}
|
|
}
|
|
height = val;
|
|
PA_UNLOCK(buff);
|
|
PA_FREE(buff);
|
|
}
|
|
|
|
/*
|
|
* All this work is to get the text_info filled in for the current
|
|
* font in the font stack. Yuck, there must be a better way.
|
|
*/
|
|
memset (&tmp_text, 0, sizeof (tmp_text));
|
|
buff = PA_ALLOC(1);
|
|
if (buff == NULL)
|
|
{
|
|
state->top_state->out_of_memory = TRUE;
|
|
return;
|
|
}
|
|
PA_LOCK(str, char *, buff);
|
|
str[0] = ' ';
|
|
PA_UNLOCK(buff);
|
|
tmp_text.text = buff;
|
|
tmp_text.text_len = 1;
|
|
#ifdef DOM
|
|
tmp_text.text_attr = lo_GetCurrentTextAttr(state, context);
|
|
#else
|
|
tmp_text.text_attr = state->font_stack->text_attr;
|
|
#endif
|
|
FE_GetTextInfo(context, &tmp_text, &text_info);
|
|
PA_FREE(buff);
|
|
|
|
/*
|
|
* If both dimentions are bogus, no spacer.
|
|
* If only one dimension bogus, then make it 1.
|
|
*/
|
|
if ((width < 1)&&(height < 1))
|
|
{
|
|
return;
|
|
}
|
|
else if (width < 1)
|
|
{
|
|
width = 1;
|
|
}
|
|
else if (height < 1)
|
|
{
|
|
height = 1;
|
|
}
|
|
|
|
|
|
/*
|
|
* SEVERE FLOW BREAK! This may be a floating image,
|
|
* which means at this point we go do something completely
|
|
* different.
|
|
*/
|
|
if (floating != FALSE)
|
|
{
|
|
if (alignment == LO_ALIGN_RIGHT)
|
|
{
|
|
if (state->right_margin_stack == NULL)
|
|
{
|
|
x = state->right_margin - width;
|
|
}
|
|
else
|
|
{
|
|
x = state->right_margin_stack->margin - width;
|
|
}
|
|
if (x < 0)
|
|
{
|
|
x = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
x = state->left_margin;
|
|
}
|
|
|
|
y = -1;
|
|
|
|
lo_AddMarginStack(state, x, y,
|
|
width, height, 0, 0, 0, alignment);
|
|
|
|
if (state->at_begin_line != FALSE)
|
|
{
|
|
lo_FindLineMargins(context, state, TRUE);
|
|
state->x = state->left_margin;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* Will this spacer make the line too wide.
|
|
*/
|
|
if ((state->x + width) > state->right_margin)
|
|
{
|
|
line_break = TRUE;
|
|
}
|
|
else
|
|
{
|
|
line_break = FALSE;
|
|
}
|
|
|
|
/*
|
|
* if we are at the beginning of the line. There is
|
|
* no point in breaking, we are just too wide.
|
|
* Also don't break in unmapped preformatted text.
|
|
* Also can't break inside a NOBR section.
|
|
*/
|
|
if ((state->at_begin_line != FALSE)||
|
|
(state->preformatted == PRE_TEXT_YES)||
|
|
(state->breakable == FALSE))
|
|
{
|
|
line_break = FALSE;
|
|
}
|
|
|
|
/*
|
|
* break on the spacer if we have
|
|
* a break.
|
|
*/
|
|
if (line_break != FALSE)
|
|
{
|
|
lo_SoftLineBreak(context, state, TRUE);
|
|
x = state->x;
|
|
y = state->y;
|
|
}
|
|
|
|
/*
|
|
* Figure out how to align this spacer.
|
|
* baseline_inc is how much to increase the baseline
|
|
* of previous element of this line. line_inc is how
|
|
* much to increase the line height below the baseline.
|
|
*/
|
|
baseline_inc = 0;
|
|
line_inc = 0;
|
|
x_offset = 0;
|
|
y_offset = 0;
|
|
|
|
lo_CalcAlignOffsets(state, &text_info, alignment,
|
|
width, height,
|
|
&x_offset, &y_offset, &line_inc, &baseline_inc);
|
|
|
|
width += x_offset;
|
|
height += y_offset;
|
|
|
|
/*
|
|
* Change the rest of the line the way lo_AppendToLineList()
|
|
* would if we were adding a real element.
|
|
*/
|
|
eptr = state->line_list;
|
|
if (eptr != NULL)
|
|
{
|
|
while (eptr->lo_any.next != NULL)
|
|
{
|
|
eptr->lo_any.y_offset += baseline_inc;
|
|
eptr = eptr->lo_any.next;
|
|
}
|
|
eptr->lo_any.y_offset += baseline_inc;
|
|
}
|
|
|
|
state->baseline += (intn) baseline_inc;
|
|
state->line_height += (intn) (baseline_inc + line_inc);
|
|
|
|
/*
|
|
* Clean up state
|
|
*/
|
|
state->x = state->x + width;
|
|
state->linefeed_state = 0;
|
|
state->at_begin_line = FALSE;
|
|
state->trailing_space = FALSE;
|
|
state->cur_ele_type = LO_NONE;
|
|
}
|
|
#endif
|