mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 13:51:41 +00:00
Changes to make Layer/Ilayer reflow work. This should fix sites like
altavista and slashdot.org.
This commit is contained in:
parent
a867742b43
commit
ce478388e4
@ -247,6 +247,8 @@ typedef struct LO_BlockInitializeStruct_struct {
|
||||
int32 width;
|
||||
XP_Bool has_height;
|
||||
int32 height;
|
||||
uint8 percent_width;
|
||||
uint8 percent_height;
|
||||
char *name;
|
||||
char *id;
|
||||
char *above;
|
||||
@ -1258,8 +1260,8 @@ typedef struct LO_BlockQuote_struct {
|
||||
|
||||
typedef struct LO_Layer_struct {
|
||||
LO_Any lo_any;
|
||||
|
||||
Bool is_end;
|
||||
Bool is_end;
|
||||
void /* lo_LayerDocState */ *layerDoc;
|
||||
LO_BlockInitializeStruct *initParams;
|
||||
} LO_LayerStruct;
|
||||
|
||||
|
@ -70,7 +70,17 @@ struct lo_Block {
|
||||
char *source_url;
|
||||
};
|
||||
|
||||
static int lo_AppendLayerElement(MWContext *context, lo_DocState *state, int32 is_end);
|
||||
static int lo_AppendLayerElement(MWContext *context, lo_DocState *state,
|
||||
LO_BlockInitializeStruct *param,
|
||||
lo_LayerDocState *layerDoc, Bool is_end);
|
||||
|
||||
static PRBool
|
||||
lo_SetupDocStateForLayer(lo_DocState *state,
|
||||
lo_LayerDocState *layer_state,
|
||||
int32 width,
|
||||
int32 height,
|
||||
PRBool is_inflow,
|
||||
PRBool reflow);
|
||||
|
||||
#ifdef XP_MAC
|
||||
PRIVATE
|
||||
@ -614,9 +624,7 @@ lo_BeginLayer(MWContext *context,
|
||||
LO_BlockInitializeStruct *param,
|
||||
XP_Bool is_inflow);
|
||||
|
||||
#ifdef XP_MAC
|
||||
PRIVATE
|
||||
#endif
|
||||
|
||||
void
|
||||
lo_FreeBlockInitializeStruct(LO_BlockInitializeStruct *param)
|
||||
{
|
||||
@ -740,6 +748,13 @@ lo_BeginLayerTag(MWContext *context, lo_DocState *state, PA_Tag *tag)
|
||||
val = (char*)lo_FetchParamValue(context, tag, PARAM_WIDTH);
|
||||
if(val)
|
||||
{
|
||||
Bool is_percent;
|
||||
int32 ival;
|
||||
|
||||
ival = lo_ValueOrPercent(val, &is_percent);
|
||||
if (is_percent)
|
||||
param->percent_width = (uint8) ival;
|
||||
|
||||
param->has_width = TRUE;
|
||||
param->width = lo_parse_horizontal_param(val, state, context);
|
||||
XP_FREE(val);
|
||||
@ -752,6 +767,13 @@ lo_BeginLayerTag(MWContext *context, lo_DocState *state, PA_Tag *tag)
|
||||
val = (char*)lo_FetchParamValue(context, tag, PARAM_HEIGHT);
|
||||
if(val)
|
||||
{
|
||||
Bool is_percent;
|
||||
int32 ival;
|
||||
|
||||
ival = lo_ValueOrPercent(val, &is_percent);
|
||||
if (is_percent)
|
||||
param->percent_height = (uint8) ival;
|
||||
|
||||
param->has_height = TRUE;
|
||||
param->height = lo_parse_vertical_param(val, state, context);
|
||||
XP_FREE(val);
|
||||
@ -818,11 +840,14 @@ lo_BeginLayerTag(MWContext *context, lo_DocState *state, PA_Tag *tag)
|
||||
param->tag = tag;
|
||||
param->ss_tag = NULL;
|
||||
|
||||
if (lo_BeginLayer(context, state, param, tag->type == P_ILAYER))
|
||||
lo_FreeBlockInitializeStruct(param);
|
||||
lo_BeginLayer(context, state, param, tag->type == P_ILAYER);
|
||||
|
||||
/* lo_FreeBlockInitializeStruct(param); */
|
||||
}
|
||||
|
||||
static int lo_AppendLayerElement(MWContext *context, lo_DocState *state, int32 is_end)
|
||||
static int lo_AppendLayerElement(MWContext *context, lo_DocState *state,
|
||||
LO_BlockInitializeStruct *param,
|
||||
lo_LayerDocState *layerDoc, Bool is_end)
|
||||
{
|
||||
LO_LayerStruct *layer;
|
||||
layer = (LO_LayerStruct*)lo_NewElement(context, state, LO_LAYER, NULL, 0);
|
||||
@ -842,7 +867,8 @@ static int lo_AppendLayerElement(MWContext *context, lo_DocState *state, int32 i
|
||||
layer->lo_any.ele_id = NEXT_ELEMENT;
|
||||
|
||||
layer->is_end = is_end;
|
||||
layer->initParams = NULL; /* Not keeping params for now. Just trying to fix ILAYER crash. */
|
||||
layer->initParams = param;
|
||||
layer->layerDoc = layerDoc;
|
||||
|
||||
lo_AppendToLineList(context, state, (LO_Element*)layer, 0);
|
||||
|
||||
@ -1218,6 +1244,8 @@ lo_SetStyleSheetLayerProperties(MWContext *context,
|
||||
ss_num = STYLESTRUCT_GetNumber(style_struct, HEIGHT_STYLE);
|
||||
if(ss_num)
|
||||
{
|
||||
if(!XP_STRCMP(ss_num->units, "%"))
|
||||
param->percent_height = (uint8) ss_num->value;
|
||||
LO_AdjustSSUnits(ss_num, HEIGHT_STYLE, context, state);
|
||||
param->height = FEUNITS_Y((int32)ss_num->value, context);
|
||||
param->has_height = TRUE;
|
||||
@ -1225,9 +1253,19 @@ lo_SetStyleSheetLayerProperties(MWContext *context,
|
||||
}
|
||||
|
||||
/* don't set width. normal style sheets will handle it */
|
||||
/* NRA: I think we do need to set the width. But, need to check with Scott. */
|
||||
ss_num = STYLESTRUCT_GetNumber(style_struct, WIDTH_STYLE);
|
||||
if(ss_num)
|
||||
{
|
||||
if(!XP_STRCMP(ss_num->units, "%"))
|
||||
param->percent_width = (uint8) ss_num->value;
|
||||
LO_AdjustSSUnits(ss_num, WIDTH_STYLE, context, state);
|
||||
param->width = FEUNITS_X((int32)ss_num->value, context);
|
||||
param->has_width = TRUE;
|
||||
STYLESTRUCT_FreeSSNumber(style_struct, ss_num);
|
||||
}
|
||||
|
||||
prop = STYLESTRUCT_GetString(style_struct, CLIP_STYLE);
|
||||
|
||||
if(prop) {
|
||||
param->clip = lo_ParseStyleCoords(context, state, style_struct, prop);
|
||||
param->clip_expansion_policy = LO_AUTO_EXPAND_NONE;
|
||||
@ -1281,8 +1319,7 @@ lo_SetStyleSheetLayerProperties(MWContext *context,
|
||||
param->tag = NULL;
|
||||
param->ss_tag = tag;
|
||||
|
||||
if (lo_BeginLayer(context, state, param, is_inflow))
|
||||
lo_FreeBlockInitializeStruct(param);
|
||||
lo_BeginLayer(context, state, param, is_inflow);
|
||||
}
|
||||
#endif /* DOM */
|
||||
|
||||
@ -1315,7 +1352,7 @@ lo_SaveDocState(lo_Block *block, lo_DocState *state)
|
||||
}
|
||||
|
||||
static void
|
||||
lo_RestoreDocState(lo_Block *block, lo_DocState *state)
|
||||
lo_RestoreDocState(lo_Block *block, lo_DocState *state, Bool reflow)
|
||||
{
|
||||
lo_DocState *saved = block->saved_state;
|
||||
lo_FontStack *font_stack;
|
||||
@ -1334,7 +1371,8 @@ lo_RestoreDocState(lo_Block *block, lo_DocState *state)
|
||||
}
|
||||
state->top_state->body_attr = block->old_body_attr;
|
||||
|
||||
lo_SetBaseUrl(state->top_state, block->old_base_url, FALSE);
|
||||
if (!reflow)
|
||||
lo_SetBaseUrl(state->top_state, block->old_base_url, FALSE);
|
||||
|
||||
if (block->is_inflow) {
|
||||
state->line_num = saved->line_num;
|
||||
@ -1411,7 +1449,8 @@ lo_SetupDocStateForLayer(lo_DocState *state,
|
||||
lo_LayerDocState *layer_state,
|
||||
int32 width,
|
||||
int32 height,
|
||||
PRBool is_inflow)
|
||||
PRBool is_inflow,
|
||||
PRBool reflow)
|
||||
{
|
||||
lo_Block *block = layer_state->temp_block;
|
||||
MWContext *context = block->context;
|
||||
@ -1427,7 +1466,7 @@ lo_SetupDocStateForLayer(lo_DocState *state,
|
||||
state->float_list = NULL;
|
||||
state->line_list = NULL;
|
||||
|
||||
if (state->top_state->base_url)
|
||||
if (state->top_state->base_url && !reflow)
|
||||
block->old_base_url = XP_STRDUP(state->top_state->base_url);
|
||||
|
||||
if (is_inflow)
|
||||
@ -1832,19 +1871,16 @@ lo_begin_layer_internal(MWContext *context,
|
||||
inherit_visibility = (PRBool)!XP_STRCASECMP(param->visibility, "inherit");
|
||||
}
|
||||
|
||||
if (is_inflow)
|
||||
{
|
||||
/* Add a new LO_LAYER dummy layout element to the line list. Relayout will step through
|
||||
the line list and reflow the layer when the LO_LAYER element is encountered. */
|
||||
if (!lo_AppendLayerElement(context, state, FALSE))
|
||||
return;
|
||||
}
|
||||
/* Add a new LO_LAYER dummy layout element to the line list. Relayout will step through
|
||||
the line list and reflow the layer when the LO_LAYER element is encountered. */
|
||||
if (!lo_AppendLayerElement(context, state, param, layer_state, FALSE))
|
||||
return;
|
||||
|
||||
/* Reset document layout state, saving old state to be restored
|
||||
after we lay out this layer. */
|
||||
if (!lo_SetupDocStateForLayer(state, layer_state,
|
||||
block_wrap_width, layer_state->height,
|
||||
(PRBool)is_inflow)) {
|
||||
(PRBool)is_inflow, PR_FALSE)) {
|
||||
state->top_state->out_of_memory = TRUE;
|
||||
lo_DeleteLayerState(context, state, layer_state);
|
||||
return;
|
||||
@ -2128,6 +2164,12 @@ lo_BeginLayer(MWContext *context,
|
||||
if (!context->compositor || !param)
|
||||
return TRUE;
|
||||
|
||||
lo_begin_layer_internal(context, state, param, is_inflow);
|
||||
return TRUE;
|
||||
|
||||
/* We no longer recreate layers on resizes, so the following code that rehooks up
|
||||
layout's layer data structures with the JS layer objects can go away. */
|
||||
#if 0
|
||||
if (state->top_state->resize_reload && !state->in_relayout &&
|
||||
!lo_IsAnyCurrentAncestorDynamic(state) && LM_CanDoJS(context)) {
|
||||
lo_RestoreLayerClosure *closure;
|
||||
@ -2177,6 +2219,7 @@ lo_BeginLayer(MWContext *context,
|
||||
lo_begin_layer_internal(context, state, param, is_inflow);
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@ -2486,14 +2529,11 @@ lo_EndLayer(MWContext *context,
|
||||
}
|
||||
|
||||
/* Restore document layout state, if necessary */
|
||||
lo_RestoreDocState(block, state);
|
||||
lo_RestoreDocState(block, state, FALSE);
|
||||
|
||||
if (block->is_inflow)
|
||||
{
|
||||
/* Mark the </LAYER> tag by appending a LO_LAYER element to the line list. */
|
||||
if (!lo_AppendLayerElement(context, state, TRUE))
|
||||
return;
|
||||
}
|
||||
/* Mark the </(I)LAYER> tag by appending a LO_LAYER element to the line list. */
|
||||
if (!lo_AppendLayerElement(context, state, NULL, NULL, TRUE))
|
||||
return;
|
||||
|
||||
if (cell != NULL && !block->is_inflow)
|
||||
{
|
||||
@ -2558,8 +2598,6 @@ lo_EndLayer(MWContext *context,
|
||||
ET_SendLoadEvent(context, EVENT_LOAD, NULL, NULL, layer_state->id,
|
||||
state->top_state->resize_reload);
|
||||
|
||||
lo_DeleteBlock(block);
|
||||
layer_state->temp_block = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
@ -2766,7 +2804,7 @@ lo_init_block(MWContext *context, lo_DocState *state,
|
||||
layer_state->temp_block = block;
|
||||
|
||||
if (!lo_SetupDocStateForLayer(state, layer_state,
|
||||
width, layer_state->height, PR_FALSE)) {
|
||||
width, layer_state->height, PR_FALSE, PR_FALSE)) {
|
||||
lo_DeleteBlock(block);
|
||||
layer_state->temp_block = NULL;
|
||||
return NULL;
|
||||
@ -3039,3 +3077,271 @@ LO_CreateNewLayer(MWContext *context, int32 wrap_width, int32 parent_layer_id)
|
||||
|
||||
return layer_id;
|
||||
}
|
||||
|
||||
|
||||
/* Called when you see a start LO_LAYER element. Reflow version of lo_begin_layer_internal */
|
||||
void
|
||||
lo_BeginLayerReflow(MWContext *context, lo_DocState *state,
|
||||
LO_BlockInitializeStruct *param,
|
||||
lo_LayerDocState *layer_state)
|
||||
{
|
||||
lo_Block *block;
|
||||
lo_LayerDocState *parent_layer_state;
|
||||
int32 block_wrap_width, x_parent_offset, y_parent_offset;
|
||||
CL_Layer *layer, *parent_layer;
|
||||
int32 block_x, block_y;
|
||||
Bool is_inflow;
|
||||
XP_Rect bbox;
|
||||
LO_CellStruct *cell;
|
||||
lo_GroupLayerClosure *closure;
|
||||
lo_HTMLBlockClosure *content_closure;
|
||||
|
||||
if (!context->compositor || !param || !layer_state)
|
||||
return;
|
||||
|
||||
block = layer_state->temp_block;
|
||||
is_inflow = block->is_inflow;
|
||||
cell = layer_state->cell;
|
||||
layer = layer_state->layer;
|
||||
|
||||
/*
|
||||
* If this is a nested inflow layer, then flush the line list into our parent
|
||||
* (without introducing a line break). This ensures that whatever line changes
|
||||
* (specifically shifting of cell origin) that occur while laying out this ilayer
|
||||
* are reflected in our parent.
|
||||
*/
|
||||
if (lo_InsideInflowLayer(state) && is_inflow)
|
||||
{
|
||||
lo_rl_AddBreakAndFlushLine(context, state, LO_LINEFEED_BREAK_SOFT, LO_CLEAR_NONE, FALSE);
|
||||
}
|
||||
|
||||
/* In-flow layers use coordinates that are relative to their
|
||||
"natural", in-flow position. */
|
||||
if (block->is_inflow) {
|
||||
block->x_offset = state->x;
|
||||
block->y_offset = state->y;
|
||||
} else {
|
||||
block->x_offset = 0;
|
||||
block->y_offset = 0;
|
||||
}
|
||||
|
||||
x_parent_offset = y_parent_offset = 0;
|
||||
parent_layer_state = lo_CurrentLayerState(state);
|
||||
parent_layer = parent_layer_state->layer;
|
||||
if (parent_layer) /* Paranoia */
|
||||
lo_GetLayerXYShift(parent_layer, &x_parent_offset, &y_parent_offset);
|
||||
|
||||
/*
|
||||
* Get the X position of the block
|
||||
*/
|
||||
if (param->has_left)
|
||||
{
|
||||
block_x = param->left;
|
||||
} else {
|
||||
if (block->is_inflow) {
|
||||
block_x = 0;
|
||||
} else {
|
||||
block_x = state->x - x_parent_offset;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the Y position of the block
|
||||
*/
|
||||
if (param->has_top)
|
||||
{
|
||||
block_y = param->top;
|
||||
} else {
|
||||
if (block->is_inflow) {
|
||||
block_y = 0;
|
||||
} else {
|
||||
block_y = state->y - y_parent_offset;
|
||||
}
|
||||
}
|
||||
|
||||
XP_BZERO(&bbox, sizeof(bbox));
|
||||
|
||||
/*
|
||||
* Get the width parameter, in absolute or percentage.
|
||||
* If percentage, make it absolute.
|
||||
*/
|
||||
if (param->has_width)
|
||||
block_wrap_width = param->width;
|
||||
else if (param->has_left)
|
||||
block_wrap_width = state->right_margin - param->left;
|
||||
else
|
||||
block_wrap_width = state->right_margin - state->x;
|
||||
|
||||
|
||||
/*
|
||||
* Parse the comma separated coordinate list into an
|
||||
* array of integers.
|
||||
*/
|
||||
if (param->clip)
|
||||
{
|
||||
bbox = *param->clip;
|
||||
|
||||
/* Don't allow the layer's clip to expand */
|
||||
block->clip_expansion_policy = param->clip_expansion_policy;
|
||||
} else {
|
||||
/* Allow the clip to expand to include the layer's contents. */
|
||||
block->clip_expansion_policy = LO_AUTO_EXPAND_CLIP;
|
||||
if (param->has_width)
|
||||
bbox.right = block_wrap_width;
|
||||
}
|
||||
|
||||
if (param->has_height) {
|
||||
layer_state->height = param->height;
|
||||
/* If no CLIP set, set initial bottom edge of layer clip to be
|
||||
the same as HEIGHT. */
|
||||
if (block->clip_expansion_policy & LO_AUTO_EXPAND_CLIP_BOTTOM)
|
||||
bbox.bottom = param->height;
|
||||
}
|
||||
|
||||
/* Treat any value of OVERFLOW, except "hidden" to be the same as
|
||||
"visible". For compatibility with the older CSS positioning
|
||||
spec, we also treat "none" specially. Can't set OVERFLOW
|
||||
unless HEIGHT is provided. */
|
||||
if (param->has_height &&
|
||||
param->overflow &&
|
||||
XP_STRCASECMP(param->overflow, "none") &&
|
||||
XP_STRCASECMP(param->overflow, "visible")) {
|
||||
|
||||
/* Constrain all drawing to {0, 0, width, height} box */
|
||||
XP_Rect *viewRect = &layer_state->viewRect;
|
||||
viewRect->left = 0;
|
||||
viewRect->top = 0;
|
||||
viewRect->right = block_wrap_width;
|
||||
viewRect->bottom = param->height;
|
||||
}
|
||||
|
||||
/* Reset document layout state, saving old state to be restored
|
||||
after we lay out this layer. */
|
||||
if (!lo_SetupDocStateForLayer(state, layer_state,
|
||||
block_wrap_width, layer_state->height,
|
||||
(PRBool)is_inflow, PR_TRUE)) {
|
||||
state->top_state->out_of_memory = TRUE;
|
||||
lo_DeleteLayerState(context, state, layer_state);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Reset cell struct variables that depend on the doc state */
|
||||
cell->ele_id = NEXT_ELEMENT;
|
||||
cell->x = state->x;
|
||||
cell->y = state->y;
|
||||
cell->width = 0;
|
||||
cell->height = 0;
|
||||
cell->x_offset = 0;
|
||||
cell->y_offset = 0;
|
||||
|
||||
|
||||
closure = (lo_GroupLayerClosure *)CL_GetLayerClientData(layer);
|
||||
if (closure)
|
||||
{
|
||||
/* Reset group layer closure's properties */
|
||||
XP_ASSERT(closure->type == LO_GROUP_LAYER);
|
||||
closure->x_offset = block->x_offset;
|
||||
closure->y_offset = block->y_offset;
|
||||
closure->wrap_width = block_wrap_width;
|
||||
}
|
||||
|
||||
/* Move layer into position. Set clip dimensions and initial visibility. */
|
||||
LO_MoveLayer(layer, block_x, block_y);
|
||||
LO_SetLayerBbox(layer, &bbox);
|
||||
lo_expand_parent_bbox(layer);
|
||||
CL_ChangeLayerFlag(layer, CL_HIDDEN, hidden);
|
||||
|
||||
/* Resize the layer */
|
||||
CL_ResizeLayer(layer, block_wrap_width, layer_state->height);
|
||||
|
||||
/* Push this layer on the layer stack */
|
||||
lo_PushLayerState(state->top_state, layer_state);
|
||||
state->layer_nest_level++;
|
||||
}
|
||||
|
||||
/* Called when the end LO_LAYER element is seen by the reflow code */
|
||||
void
|
||||
lo_EndLayerReflow(MWContext *context, lo_DocState *state)
|
||||
{
|
||||
lo_LayerDocState *layer_state = lo_CurrentLayerState(state);
|
||||
lo_Block *block = layer_state->temp_block;
|
||||
LO_CellStruct *cell = NULL;
|
||||
int32 right_edge;
|
||||
|
||||
/* During destruction, the compositor can disappear out from underneath us. */
|
||||
if (!context->compositor || !block)
|
||||
return;
|
||||
|
||||
if (! block->is_inflow) {
|
||||
lo_EndLayoutDuringReflow(context, state);
|
||||
}
|
||||
else {
|
||||
lo_rl_FlushLineList(context, state, LO_LINEFEED_BREAK_SOFT, LO_CLEAR_NONE, FALSE);
|
||||
}
|
||||
|
||||
cell = lo_compose_block(context, state, block);
|
||||
|
||||
/* For an in-flow layer, expand the enclosing cell's size on the
|
||||
right and bottom edges to contain any descendant
|
||||
layers. However, we only do this for ILAYER tags, not for
|
||||
layers created as a result of 'position:relative' applied to
|
||||
style-sheet elements. */
|
||||
if (block->is_inflow && !block->uses_ss_positioning) {
|
||||
int32 grow_width, grow_height;
|
||||
XP_Rect bbox;
|
||||
|
||||
CL_GetLayerBbox(block->layer, &bbox);
|
||||
grow_width = (bbox.right - cell->width);
|
||||
grow_height = (bbox.bottom - cell->height);
|
||||
|
||||
/* Position of right-edge of cell containing layer */
|
||||
right_edge = state->x;
|
||||
|
||||
/* If the inflow layer is caused to grow vertically, force a
|
||||
line break. */
|
||||
if (grow_height > 0) {
|
||||
lo_SetLineBreakState ( context, state, FALSE, LO_LINEFEED_BREAK_HARD, 1, TRUE);
|
||||
cell->height = bbox.bottom;
|
||||
state->y += grow_height;
|
||||
}
|
||||
|
||||
/* Compute new position of cell's right edge. */
|
||||
if (grow_width > 0) {
|
||||
right_edge += grow_width;
|
||||
cell->width = bbox.right;
|
||||
}
|
||||
|
||||
/* Set minimum and maximum possible layout widths so that any
|
||||
enclosing table cells will be dimensioned properly. */
|
||||
if (right_edge + state->win_right > state->max_width)
|
||||
state->max_width = right_edge + state->win_right;
|
||||
if (right_edge + state->win_right > state->min_width)
|
||||
state->min_width = right_edge + state->win_right;
|
||||
}
|
||||
|
||||
/* Restore document layout state, if necessary */
|
||||
lo_RestoreDocState(block, state, TRUE);
|
||||
|
||||
if (cell != NULL && !block->is_inflow)
|
||||
{
|
||||
int32 max_y;
|
||||
|
||||
cell->next = NULL;
|
||||
cell->ele_id = NEXT_ELEMENT;
|
||||
lo_RenumberCell(state, cell);
|
||||
|
||||
/* XXX - Do we really want to expand the document size to
|
||||
include the layer ? */
|
||||
max_y = cell->y + cell->y_offset + cell->height;
|
||||
if (max_y > state->max_height)
|
||||
{
|
||||
state->max_height = max_y;
|
||||
}
|
||||
}
|
||||
state->layer_nest_level--;
|
||||
lo_PopLayerState(state);
|
||||
|
||||
ET_SendLoadEvent(context, EVENT_LOAD, NULL, NULL, layer_state->id,
|
||||
TRUE);
|
||||
|
||||
}
|
@ -26,6 +26,7 @@
|
||||
#endif
|
||||
#include "layers.h"
|
||||
#include "pa_parse.h"
|
||||
#include "laylayer.h"
|
||||
|
||||
#define IL_CLIENT /* XXXM12N Defined by Image Library clients */
|
||||
#include "libimg.h" /* Image Library public API. */
|
||||
@ -764,6 +765,20 @@ lo_ScrapeElement(MWContext *context, LO_Element *element, Bool freeTableOrCellSt
|
||||
element->lo_textBlock.break_table = NULL;
|
||||
}
|
||||
break;
|
||||
case LO_LAYER:
|
||||
if ( element->lo_layer.initParams )
|
||||
{
|
||||
lo_FreeBlockInitializeStruct( element->lo_layer.initParams );
|
||||
element->lo_layer.initParams = NULL;
|
||||
}
|
||||
if ( element->lo_layer.layerDoc )
|
||||
{
|
||||
/* We are going to let the layer cleanup function,
|
||||
lo_DeleteLayerState() clean the lo_Block structure
|
||||
on the layer doc state (lo_LayerDocState) */
|
||||
element->lo_layer.layerDoc = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2837,7 +2837,7 @@ lo_ActivateImageLayer(MWContext *context, LO_ImageStruct *image)
|
||||
/* Move layer to new position and unhide it. */
|
||||
CL_MoveLayer(layer, x, y);
|
||||
CL_SetLayerHidden(layer, PR_FALSE);
|
||||
image->ele_attrmask |= LO_ELE_DRAWN;
|
||||
/* image->ele_attrmask |= LO_ELE_DRAWN; */
|
||||
|
||||
/* In order to increase the perceived speed of image loading,
|
||||
non-backdrop, non-icon images have the delayed icon, ALT text
|
||||
|
@ -51,7 +51,7 @@ struct lo_LayerDocState
|
||||
CL_Layer *layer;
|
||||
void *mocha_object;
|
||||
lo_DocLists *doc_lists; /* Layout element lists, e.g. embeds, forms */
|
||||
lo_Block *temp_block; /* Data used only during HTML layer layout */
|
||||
lo_Block *temp_block; /* Data used during HTML layer layout and reflow */
|
||||
};
|
||||
|
||||
struct lo_LayerStack {
|
||||
|
@ -1092,165 +1092,9 @@ lo_FlushLineList(MWContext *context, lo_DocState *state, uint32 break_type, uint
|
||||
{
|
||||
|
||||
LO_LinefeedStruct *linefeed;
|
||||
/*
|
||||
LO_Element **line_array;
|
||||
*/
|
||||
/* int32 justification_remainder=0;*/
|
||||
/*
|
||||
#ifdef XP_WIN16
|
||||
int32 a_size;
|
||||
int32 a_indx;
|
||||
int32 a_line;
|
||||
XP_Block *larray_array;
|
||||
#endif
|
||||
*/
|
||||
/* XP_WIN16 */
|
||||
|
||||
lo_UpdateStateWhileFlushingLine( context, state );
|
||||
|
||||
/*
|
||||
if (state->top_state->nothing_displayed != FALSE) {
|
||||
*/
|
||||
/*
|
||||
* If we are displaying elements we are
|
||||
* no longer in the HEAD section of the HTML
|
||||
* we are in the BODY section.
|
||||
*/
|
||||
/*
|
||||
state->top_state->in_head = FALSE;
|
||||
state->top_state->in_body = TRUE;
|
||||
|
||||
lo_use_default_doc_background(context, state);
|
||||
state->top_state->nothing_displayed = FALSE;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
* There is a break at the end of this line.
|
||||
* this may change min_width.
|
||||
*/
|
||||
/*
|
||||
{
|
||||
int32 new_break_holder;
|
||||
int32 min_width;
|
||||
int32 indent;
|
||||
|
||||
new_break_holder = state->x;
|
||||
min_width = new_break_holder - state->break_holder;
|
||||
indent = state->list_stack->old_left_margin - state->win_left;
|
||||
min_width += indent;
|
||||
if (min_width > state->min_width)
|
||||
{
|
||||
state->min_width = min_width;
|
||||
}
|
||||
*/
|
||||
/* If we are not within <NOBR> content, allow break_holder
|
||||
* to be set to the new position where a line break can occur.
|
||||
* This fixes BUG #70782
|
||||
*/
|
||||
/*
|
||||
if (state->breakable != FALSE) {
|
||||
state->break_holder = new_break_holder;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
* If in a division centering or right aligning this line
|
||||
*/
|
||||
/*
|
||||
if ((state->align_stack != NULL)&&(state->delay_align == FALSE))
|
||||
{
|
||||
int32 push_right;
|
||||
LO_Element *tptr;
|
||||
|
||||
if (state->align_stack->alignment == LO_ALIGN_CENTER)
|
||||
{
|
||||
push_right = (state->right_margin - state->x) / 2;
|
||||
}
|
||||
else if (state->align_stack->alignment == LO_ALIGN_RIGHT)
|
||||
{
|
||||
push_right = state->right_margin - state->x;
|
||||
}
|
||||
else if(state->align_stack->alignment == LO_ALIGN_JUSTIFY)
|
||||
{
|
||||
push_right = lo_calc_push_right_for_justify(state, &justification_remainder);
|
||||
}
|
||||
else
|
||||
{
|
||||
push_right = 0;
|
||||
}
|
||||
|
||||
if ((push_right > 0 || justification_remainder)
|
||||
&&(state->line_list != NULL))
|
||||
{
|
||||
int32 count = 0;
|
||||
int32 move_delta;
|
||||
tptr = state->line_list;
|
||||
|
||||
if(state->align_stack->alignment == LO_ALIGN_JUSTIFY)
|
||||
move_delta = 0;
|
||||
else
|
||||
move_delta = push_right;
|
||||
|
||||
while (tptr != NULL)
|
||||
{
|
||||
*/
|
||||
/*
|
||||
* We don't shift over inflow layers, since their contents
|
||||
* have already been shifted over.
|
||||
*/
|
||||
/*
|
||||
* We also don't shift bullets of type BULLET_MQUOTE.
|
||||
*/
|
||||
/*
|
||||
if (((tptr->type != LO_CELL)||
|
||||
(!tptr->lo_cell.cell_inflow_layer))&&
|
||||
((tptr->type != LO_BULLET)||
|
||||
((tptr->type == LO_BULLET)&&
|
||||
(tptr->lo_bullet.bullet_type != BULLET_MQUOTE))))
|
||||
{
|
||||
tptr->lo_any.x += move_delta;
|
||||
}
|
||||
*/
|
||||
|
||||
/* justification push_rights are additive */
|
||||
/*
|
||||
if(state->align_stack->alignment == LO_ALIGN_JUSTIFY)
|
||||
{
|
||||
move_delta += push_right;
|
||||
*/
|
||||
/* if there is a justification remainder, add a pixel
|
||||
* to the first n word breaks
|
||||
*/
|
||||
/*
|
||||
if(count < justification_remainder)
|
||||
move_delta++;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
* Note that if this is an inflow layer, we don't want
|
||||
* to shift it since the alignment has already propogated
|
||||
* to its contents.
|
||||
*/
|
||||
/*
|
||||
if ((tptr->type == LO_CELL) &&
|
||||
!tptr->lo_cell.cell_inflow_layer)
|
||||
{
|
||||
lo_ShiftCell((LO_CellStruct *)tptr, move_delta, 0);
|
||||
}
|
||||
tptr = tptr->lo_any.next;
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
if(state->align_stack->alignment == LO_ALIGN_JUSTIFY)
|
||||
state->x = state->right_margin;
|
||||
else
|
||||
state->x += push_right;
|
||||
}
|
||||
}
|
||||
*/
|
||||
#if 0
|
||||
/* apply line-height stack mods (if exists) */
|
||||
if(state->line_height_stack && state->end_last_line)
|
||||
@ -1318,122 +1162,6 @@ lo_FlushLineList(MWContext *context, lo_DocState *state, uint32 break_type, uint
|
||||
if (linefeed != NULL)
|
||||
{
|
||||
lo_AppendLineFeed( context, state, linefeed, breaking, TRUE );
|
||||
|
||||
/*
|
||||
LO_Element *tptr;
|
||||
|
||||
if (breaking != FALSE)
|
||||
{
|
||||
linefeed->ele_attrmask |= LO_ELE_BREAKING;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
* Horrible bitflag overuse!!! For multicolumn text
|
||||
* we need to know if a line of text can be used for
|
||||
* a column break, or if it cannot because it is wrapped
|
||||
* around some object in the margin. For lines that can be
|
||||
* used for column breaks, we will set the BREAKABLE
|
||||
* flag in their element mask.
|
||||
*/
|
||||
/*
|
||||
if ((state->left_margin_stack == NULL)&&
|
||||
(state->right_margin_stack == NULL))
|
||||
{
|
||||
linefeed->ele_attrmask |= LO_ELE_BREAKABLE;
|
||||
}
|
||||
|
||||
if ((state->align_stack != NULL)&&
|
||||
(state->delay_align != FALSE)&&
|
||||
(state->align_stack->alignment != LO_ALIGN_LEFT))
|
||||
{
|
||||
if (state->align_stack->alignment == LO_ALIGN_CENTER)
|
||||
{
|
||||
linefeed->ele_attrmask |= LO_ELE_DELAY_CENTER;
|
||||
}
|
||||
else if (state->align_stack->alignment == LO_ALIGN_RIGHT)
|
||||
{
|
||||
linefeed->ele_attrmask |= LO_ELE_DELAY_RIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
tptr = state->line_list;
|
||||
|
||||
if (tptr == NULL)
|
||||
{
|
||||
state->line_list = (LO_Element *)linefeed;
|
||||
linefeed->prev = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (tptr != NULL)
|
||||
{
|
||||
*/
|
||||
/*
|
||||
* If the display is blocked for an element
|
||||
* we havn't reached yet, check to see if
|
||||
* it is in this line, and if so, save its
|
||||
* y position.
|
||||
*/
|
||||
/*
|
||||
if ((state->display_blocked != FALSE)&&
|
||||
#ifdef EDITOR
|
||||
(!state->edit_relayout_display_blocked)&&
|
||||
#endif
|
||||
(state->is_a_subdoc == SUBDOC_NOT)&&
|
||||
(state->display_blocking_element_y == 0)&&
|
||||
(state->display_blocking_element_id != -1)&&
|
||||
(tptr->lo_any.ele_id >=
|
||||
state->display_blocking_element_id))
|
||||
{
|
||||
state->display_blocking_element_y =
|
||||
state->y;
|
||||
*/
|
||||
/*
|
||||
* Special case, if the blocking element
|
||||
* is on the first line, no blocking
|
||||
* at all needs to happen.
|
||||
*/
|
||||
/*
|
||||
if (state->y == state->win_top)
|
||||
{
|
||||
state->display_blocked = FALSE;
|
||||
FE_SetDocPosition(context,
|
||||
FE_VIEW, 0, state->base_y);
|
||||
if (context->compositor)
|
||||
{
|
||||
XP_Rect rect;
|
||||
|
||||
rect.left = 0;
|
||||
rect.top = 0;
|
||||
rect.right = state->win_width;
|
||||
rect.bottom = state->win_height;
|
||||
CL_UpdateDocumentRect(context->compositor,
|
||||
&rect, (PRBool)FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
tptr->lo_any.line_height = state->line_height;
|
||||
*/
|
||||
/*
|
||||
* Special for bullets of type BULLET_MQUOTE
|
||||
* They should always be as tall as the line.
|
||||
*/
|
||||
/*
|
||||
if ((tptr->type == LO_BULLET)&&
|
||||
(tptr->lo_bullet.bullet_type ==
|
||||
BULLET_MQUOTE))
|
||||
{
|
||||
tptr->lo_any.y_offset = 0;
|
||||
tptr->lo_any.height =
|
||||
tptr->lo_any.line_height;
|
||||
}
|
||||
tptr = tptr->lo_any.next;
|
||||
}
|
||||
linefeed->prev = tptr;
|
||||
}
|
||||
state->x += linefeed->width;
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1448,180 +1176,7 @@ lo_FlushLineList(MWContext *context, lo_DocState *state, uint32 break_type, uint
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* We are in a layer within this (sub)doc, stuff the line there instead.
|
||||
*/
|
||||
if (state->layer_nest_level > 0)
|
||||
{
|
||||
lo_AddLineListToLayer(context, state, (LO_Element *)linefeed);
|
||||
state->line_list = NULL;
|
||||
state->old_break = NULL;
|
||||
state->old_break_block = NULL;
|
||||
state->old_break_pos = -1;
|
||||
state->old_break_width = 0;
|
||||
state->baseline = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If necessary, grow the line array to hold more lines.
|
||||
*/
|
||||
/*
|
||||
#ifdef XP_WIN16
|
||||
a_size = SIZE_LIMIT / sizeof(LO_Element *);
|
||||
a_indx = (state->line_num - 1) / a_size;
|
||||
a_line = state->line_num - (a_indx * a_size);
|
||||
|
||||
XP_LOCK_BLOCK(larray_array, XP_Block *, state->larray_array);
|
||||
state->line_array = larray_array[a_indx];
|
||||
|
||||
if (a_line == a_size)
|
||||
{
|
||||
state->line_array = XP_ALLOC_BLOCK(LINE_INC *
|
||||
sizeof(LO_Element *));
|
||||
if (state->line_array == NULL)
|
||||
{
|
||||
XP_UNLOCK_BLOCK(state->larray_array);
|
||||
state->top_state->out_of_memory = TRUE;
|
||||
return;
|
||||
}
|
||||
XP_LOCK_BLOCK(line_array, LO_Element **, state->line_array);
|
||||
line_array[0] = NULL;
|
||||
XP_UNLOCK_BLOCK(state->line_array);
|
||||
state->line_array_size = LINE_INC;
|
||||
|
||||
state->larray_array_size++;
|
||||
XP_UNLOCK_BLOCK(state->larray_array);
|
||||
state->larray_array = XP_REALLOC_BLOCK(
|
||||
state->larray_array, (state->larray_array_size
|
||||
* sizeof(XP_Block)));
|
||||
if (state->larray_array == NULL)
|
||||
{
|
||||
state->top_state->out_of_memory = TRUE;
|
||||
return;
|
||||
}
|
||||
XP_LOCK_BLOCK(larray_array, XP_Block *, state->larray_array);
|
||||
larray_array[state->larray_array_size - 1] = state->line_array;
|
||||
state->line_array = larray_array[a_indx];
|
||||
}
|
||||
else if (a_line >= state->line_array_size)
|
||||
{
|
||||
state->line_array_size += LINE_INC;
|
||||
if (state->line_array_size > a_size)
|
||||
{
|
||||
state->line_array_size = (intn)a_size;
|
||||
}
|
||||
state->line_array = XP_REALLOC_BLOCK(state->line_array,
|
||||
(state->line_array_size * sizeof(LO_Element *)));
|
||||
if (state->line_array == NULL)
|
||||
{
|
||||
XP_UNLOCK_BLOCK(state->larray_array);
|
||||
state->top_state->out_of_memory = TRUE;
|
||||
return;
|
||||
}
|
||||
larray_array[a_indx] = state->line_array;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
* Place this line of elements into the line array.
|
||||
*/
|
||||
/*
|
||||
XP_LOCK_BLOCK(line_array, LO_Element **, state->line_array);
|
||||
line_array[a_line - 1] = state->line_list;
|
||||
XP_UNLOCK_BLOCK(state->line_array);
|
||||
|
||||
XP_UNLOCK_BLOCK(state->larray_array);
|
||||
#else
|
||||
if (state->line_num > state->line_array_size)
|
||||
{
|
||||
int32 line_inc;
|
||||
|
||||
if (state->line_array_size > (LINE_INC * 10))
|
||||
{
|
||||
line_inc = state->line_array_size / 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
line_inc = LINE_INC;
|
||||
}
|
||||
|
||||
state->line_array = XP_REALLOC_BLOCK(state->line_array,
|
||||
((state->line_array_size + line_inc) *
|
||||
sizeof(LO_Element *)));
|
||||
if (state->line_array == NULL)
|
||||
{
|
||||
state->top_state->out_of_memory = TRUE;
|
||||
return;
|
||||
}
|
||||
state->line_array_size += line_inc;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
* Place this line of elements into the line array.
|
||||
*/
|
||||
/*
|
||||
XP_LOCK_BLOCK(line_array, LO_Element **, state->line_array);
|
||||
line_array[state->line_num - 1] = state->line_list;
|
||||
XP_UNLOCK_BLOCK(state->line_array);
|
||||
#endif */
|
||||
|
||||
/* XP_WIN16 */
|
||||
|
||||
/*
|
||||
* connect the complete doubly linked list between this line
|
||||
* and the last one.
|
||||
*/
|
||||
/*
|
||||
if (state->end_last_line != NULL)
|
||||
{
|
||||
state->end_last_line->lo_any.next = state->line_list;
|
||||
state->line_list->lo_any.prev = state->end_last_line;
|
||||
}
|
||||
state->end_last_line = (LO_Element *)linefeed;
|
||||
|
||||
state->line_list = NULL;
|
||||
state->line_num++;
|
||||
*/
|
||||
/*
|
||||
*Don't draw if we're doing layers...we'll just refresh when the
|
||||
* the layer size increases.
|
||||
*/
|
||||
/*
|
||||
#ifdef LAYERS
|
||||
*/
|
||||
/*
|
||||
* Have the front end display this line.
|
||||
*/
|
||||
/* For layers, only draw if a compositor doesn't exist */
|
||||
/*
|
||||
if (!context->compositor)
|
||||
*/
|
||||
/* We need to supply a display rectangle that is guaranteed to
|
||||
encompass all elements on the line. The special 0x3fffffff
|
||||
value is approximately half the range of a 32-bit int, so
|
||||
it leaves room for overflow if arithmetic is done on these
|
||||
values. */
|
||||
/*
|
||||
lo_DisplayLine(context, state, (state->line_num - 2),
|
||||
0, 0, 0x3fffffffL, 0x3fffffffL);
|
||||
#else
|
||||
lo_DisplayLine(context, state, (state->line_num - 2),
|
||||
0, 0, 0x3fffffffL, 0x3fffffffL);
|
||||
#endif */ /* LAYERS */
|
||||
|
||||
lo_UpdateStateAfterFlushingLine( context, state, linefeed, FALSE );
|
||||
/*
|
||||
* We are starting a new line. Clear any old break
|
||||
* positions left over, clear the line_list, and increase
|
||||
* the line number.
|
||||
*/
|
||||
/*
|
||||
state->old_break = NULL;
|
||||
state->old_break_block = NULL;
|
||||
state->old_break_pos = -1;
|
||||
state->old_break_width = 0;
|
||||
state->baseline = 0;
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
@ -4081,6 +3636,72 @@ static void *hooked_data_object = NULL;
|
||||
static intn hooked_status = 0;
|
||||
static PA_Tag *hooked_tag = NULL;
|
||||
|
||||
#ifdef DOM
|
||||
char *element_names[] = {
|
||||
"NONE",
|
||||
"TEXT",
|
||||
"LINEFEED",
|
||||
"HRULE",
|
||||
"IMAGE",
|
||||
"BULLET",
|
||||
"FORM_ELE",
|
||||
"SUBDOC",
|
||||
"TABLE",
|
||||
"CELL",
|
||||
"EMBED",
|
||||
"EDGE",
|
||||
"JAVA",
|
||||
"SCRIPT",
|
||||
"OBJECT",
|
||||
"PARAGRAPH",
|
||||
"CENTER",
|
||||
"MULTICOL",
|
||||
"FLOAT",
|
||||
"TEXTBLOCK",
|
||||
"LIST",
|
||||
"DESCTITLE",
|
||||
"DESCTEXT",
|
||||
"BLOCKQUOTE",
|
||||
"LAYER",
|
||||
"HEADING",
|
||||
"SPAN",
|
||||
"BUILTIN",
|
||||
"SPACER",
|
||||
"SUPER",
|
||||
"SUB"
|
||||
};
|
||||
|
||||
static void
|
||||
DumpNodeElements(DOM_Node *node)
|
||||
{
|
||||
#ifdef DEBUG_shaver
|
||||
LO_Element *eptr;
|
||||
if (node->type != NODE_TYPE_ELEMENT &&
|
||||
node->type != NODE_TYPE_TEXT)
|
||||
return;
|
||||
fprintf(stderr, "%s %s elements:",
|
||||
PA_TagString(ELEMENT_PRIV(node)->tagtype),
|
||||
node->name ? node->name : "");
|
||||
if (ELEMENT_PRIV(node)->tagtype == P_TABLE_ROW ||
|
||||
ELEMENT_PRIV(node)->tagtype == P_TABLE_DATA) {
|
||||
fprintf(stderr, " <NOT REALLY AN ELEMENT>\n");
|
||||
return;
|
||||
}
|
||||
eptr = ELEMENT_PRIV(node)->ele_start;
|
||||
if (!eptr) {
|
||||
fprintf(stderr, " <none> (SHOULD REMOVE FROM TREE!)\n");
|
||||
return;
|
||||
}
|
||||
while (eptr && eptr != ELEMENT_PRIV(node)->ele_end) {
|
||||
fprintf(stderr, " %s", element_names[eptr->type]);
|
||||
eptr = eptr->lo_any.next;
|
||||
}
|
||||
if (eptr)
|
||||
fprintf(stderr, " %s", element_names[eptr->type]);
|
||||
fprintf(stderr, "\n");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/*************************************
|
||||
* Function: LO_ProcessTag
|
||||
@ -8145,7 +7766,22 @@ void lo_AppendLineListToLineArray( MWContext *context, lo_DocState *state, LO_El
|
||||
void lo_UpdateStateAfterFlushingLine( MWContext *context, lo_DocState *state, LO_LinefeedStruct *linefeed, Bool inRelayout )
|
||||
{
|
||||
/* LO_LinefeedStruct *linefeed; */
|
||||
|
||||
|
||||
/*
|
||||
* We are in a layer within this (sub)doc, stuff the line there instead.
|
||||
*/
|
||||
if (state->layer_nest_level > 0)
|
||||
{
|
||||
lo_AddLineListToLayer(context, state, (LO_Element *)linefeed);
|
||||
state->line_list = NULL;
|
||||
state->old_break = NULL;
|
||||
state->old_break_block = NULL;
|
||||
state->old_break_pos = -1;
|
||||
state->old_break_width = 0;
|
||||
state->baseline = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
lo_AppendLineListToLineArray( context, state, (LO_Element *) linefeed );
|
||||
|
||||
/*
|
||||
|
@ -1202,7 +1202,6 @@ extern LO_AnchorData *lo_GetElementAnchor(LO_Element *element);
|
||||
extern void lo_GetElementFGColor(LO_Element *element, LO_Color *color);
|
||||
extern void lo_SetElementFGColor(LO_Element *element, LO_Color *color);
|
||||
|
||||
extern void lo_ShiftElementList(LO_Element *, int32, int32);
|
||||
extern void lo_RenumberCell(lo_DocState *, LO_CellStruct *);
|
||||
extern void lo_ShiftCell(LO_CellStruct *, int32, int32);
|
||||
extern int32 lo_CleanTextWhitespace(char *, int32);
|
||||
@ -1468,6 +1467,14 @@ extern void lo_SetupStateForBeginMulticol( lo_DocState *state, lo_MultiCol *mult
|
||||
/* Common code for layout and relayout of spacers */
|
||||
extern void lo_LayoutSpacerElement(MWContext *context, lo_DocState *state, LO_SpacerStruct *spacer, Bool relayout);
|
||||
|
||||
/* Reflow of layers */
|
||||
extern void lo_BeginLayerReflow(MWContext *context, lo_DocState *state,
|
||||
LO_BlockInitializeStruct *param,
|
||||
lo_LayerDocState *layer_state);
|
||||
extern void lo_EndLayerReflow(MWContext *context, lo_DocState *state);
|
||||
|
||||
extern void lo_FreeBlockInitializeStruct(LO_BlockInitializeStruct *param);
|
||||
|
||||
/*
|
||||
* Adds a soft line break to the end of the line list and adds the line list to the line array.
|
||||
* Resets line list to NULL. Should be used during relayout only.
|
||||
@ -1486,6 +1493,10 @@ extern void lo_PrepareElementForReuse( MWContext *context, lo_DocState *state, L
|
||||
extern void LO_Reflow(MWContext *context, lo_DocState * state, LO_Element *startElement,
|
||||
LO_Element *endElement);
|
||||
|
||||
/* Reflow version of lo_FlushLineList() */
|
||||
extern void lo_rl_FlushLineList( MWContext *context, lo_DocState *state,
|
||||
uint32 break_type, uint32 clear_type, Bool breaking );
|
||||
|
||||
extern Bool lo_IsDummyLayoutElement(LO_Element *ele);
|
||||
|
||||
/* Useful Macros */
|
||||
|
@ -143,7 +143,8 @@ void lo_FillInBuiltinGeometry(lo_DocState *state, LO_BuiltinStruct *builtin,
|
||||
Bool relayout);
|
||||
void lo_UpdateStateAfterBuiltinLayout (lo_DocState *state, LO_BuiltinStruct *builtin,
|
||||
int32 line_inc, int32 baseline_inc);
|
||||
|
||||
static void
|
||||
lo_rl_SetLayerDimensions( lo_RelayoutState *relay_state, LO_BlockInitializeStruct *layerParams );
|
||||
|
||||
/* NRA - 10/3/97: Main Relayout Entry Point
|
||||
* This function walks through the layout element list and re-lays out
|
||||
@ -1530,25 +1531,104 @@ lo_rl_FitTextBlock( lo_RelayoutState *relay_state, LO_Element *lo_ele )
|
||||
return next;
|
||||
}
|
||||
|
||||
static void
|
||||
lo_rl_SetLayerDimensions( lo_RelayoutState *relay_state, LO_BlockInitializeStruct *layerParams )
|
||||
{
|
||||
XP_ASSERT(layerParams != NULL);
|
||||
if (layerParams)
|
||||
{
|
||||
if (layerParams->percent_width > 0)
|
||||
{
|
||||
int32 parent_width = lo_GetEnclosingLayerWidth(relay_state->doc_state);
|
||||
layerParams->width = (parent_width * layerParams->percent_width) / 100;
|
||||
}
|
||||
|
||||
if (layerParams->percent_height > 0)
|
||||
{
|
||||
int32 parent_height = lo_GetEnclosingLayerHeight(relay_state->doc_state);
|
||||
layerParams->height = (parent_height * layerParams->percent_height) / 100;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static LO_Element *
|
||||
lo_rl_FitLayer( lo_RelayoutState *relay_state, LO_Element *lo_ele )
|
||||
{
|
||||
LO_Element *next;
|
||||
LO_LayerStruct *layerEle = (LO_LayerStruct *)lo_ele;
|
||||
LO_Element *next = lo_tv_GetNextLayoutElement( relay_state->doc_state, lo_ele, TRUE );
|
||||
|
||||
XP_ASSERT(lo_ele->lo_layer.is_end == FALSE);
|
||||
|
||||
/* Skip all elements between the start and end LO_LAYER elements */
|
||||
next = lo_ele;
|
||||
do
|
||||
if(layerEle && layerEle->is_end == FALSE)
|
||||
{
|
||||
next = lo_tv_GetNextLayoutElement( relay_state->doc_state, next, TRUE);
|
||||
} while (next != NULL && next->lo_any.type != LO_LAYER);
|
||||
LO_LayerStruct *endLayer = NULL;
|
||||
LO_Element *lastFloat = NULL;
|
||||
LO_CellStruct *cell = NULL;
|
||||
|
||||
if (next->lo_any.type == LO_LAYER) {
|
||||
XP_ASSERT(next->lo_layer.is_end == TRUE);
|
||||
next = lo_tv_GetNextLayoutElement( relay_state->doc_state, next, TRUE);
|
||||
lo_AppendToLineList( relay_state->context, relay_state->doc_state, lo_ele, 0 );
|
||||
lo_rl_SetLayerDimensions( relay_state, layerEle->initParams );
|
||||
lo_BeginLayerReflow( relay_state->context, relay_state->doc_state, layerEle->initParams,
|
||||
layerEle->layerDoc );
|
||||
|
||||
if (next->lo_any.type == LO_CELL)
|
||||
{
|
||||
/* We are reflowing an ILAYER */
|
||||
cell = (LO_CellStruct *) next;
|
||||
|
||||
/* Set "next" to the layout element following the LO_CELL */
|
||||
next = lo_tv_GetNextLayoutElement( relay_state->doc_state, next, TRUE);
|
||||
|
||||
/* Set the cell's next pointer to null. We've got to fool the end layer
|
||||
code into thinking that this cell is the last element on the line list. */
|
||||
cell->next = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We are reflowing a LAYER. So, we get the cell from the lo_LayerDocState structure */
|
||||
lo_LayerDocState *layerDoc = (lo_LayerDocState *) layerEle->layerDoc;
|
||||
cell = layerDoc->cell;
|
||||
}
|
||||
|
||||
/* Assert that next is a dummy layout element marking the end of the layer */
|
||||
XP_ASSERT(next->lo_any.type == LO_LAYER && next->lo_layer.is_end == TRUE);
|
||||
endLayer = (LO_LayerStruct *) next;
|
||||
|
||||
next = cell->cell_list;
|
||||
if (next)
|
||||
{
|
||||
/* The next layout element to be fitted is the first element on the cell list.
|
||||
Once the cell list has been fitted we want to end the layer, so we append
|
||||
the end layer element to the cell list. */
|
||||
XP_ASSERT(cell->cell_list_end && cell->cell_list_end->lo_any.next == NULL);
|
||||
cell->cell_list_end->lo_any.next = (LO_Element*) endLayer;
|
||||
|
||||
/* We also need to append the cell's float list to the state's float list */
|
||||
lastFloat = lo_GetLastElementInList(relay_state->doc_state->float_list);
|
||||
if (lastFloat)
|
||||
lastFloat->lo_any.next = cell->cell_float_list;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* There is nothing on the cell's line list to reflow. So, the float list should
|
||||
also be null. The next element to be fitted is set to the end layer element. */
|
||||
XP_ASSERT(cell->cell_float_list == NULL);
|
||||
next = endLayer;
|
||||
}
|
||||
|
||||
/* Since the elements inside the layer are going to be reflowed while state->layer_nest_level
|
||||
is greater than zero, lo_FlushLineList() will append the layout elements onto the cell's
|
||||
line list. So, the cell's line list and float lists need to be initialized to null. */
|
||||
if (cell)
|
||||
{
|
||||
cell->cell_list = NULL;
|
||||
cell->cell_float_list = NULL;
|
||||
cell->cell_list_end = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
lo_EndLayerReflow( relay_state->context, relay_state->doc_state );
|
||||
lo_AppendToLineList( relay_state->context, relay_state->doc_state, lo_ele, 0 );
|
||||
}
|
||||
|
||||
return next;
|
||||
}
|
||||
|
||||
@ -1703,6 +1783,21 @@ void lo_rl_AppendLinefeedAndFlushLine( MWContext *context, lo_DocState *state, L
|
||||
lo_UpdateFEProgressBar(context, state);
|
||||
}
|
||||
|
||||
/* Reflow version of lo_FlushLineList() */
|
||||
void lo_rl_FlushLineList( MWContext *context, lo_DocState *state,
|
||||
uint32 break_type, uint32 clear_type, Bool breaking )
|
||||
{
|
||||
LO_LinefeedStruct *linefeed = NULL;
|
||||
|
||||
lo_UpdateStateWhileFlushingLine( context, state );
|
||||
linefeed = lo_NewLinefeed( state, context, break_type, clear_type );
|
||||
if (linefeed != NULL)
|
||||
{
|
||||
lo_AppendLineFeed( context, state, linefeed, breaking, FALSE );
|
||||
}
|
||||
lo_UpdateStateAfterFlushingLine( context, state, linefeed, TRUE );
|
||||
}
|
||||
|
||||
/*
|
||||
* Append a dummy layout element in the line list. When the relayout engine
|
||||
* will see this dummy element, it will call lo_LayoutFloat{Image,JavaApp,Embed}()
|
||||
@ -1738,8 +1833,6 @@ void lo_rl_ReflowCell( MWContext *context, lo_DocState *state, LO_CellStruct *ce
|
||||
lo_RelayoutState *relay_state;
|
||||
LO_Element *first;
|
||||
|
||||
LO_LockLayout();
|
||||
|
||||
/* Copy over cell line lists, float lists to state */
|
||||
lo_rl_CopyCellToState( cell, state );
|
||||
|
||||
@ -1759,8 +1852,6 @@ void lo_rl_ReflowCell( MWContext *context, lo_DocState *state, LO_CellStruct *ce
|
||||
/* Done with relayout. Destroy relayout state. */
|
||||
lo_rl_DestroyRelayoutState( relay_state );
|
||||
|
||||
LO_UnlockLayout();
|
||||
|
||||
}
|
||||
|
||||
void lo_rl_ReflowDocState( MWContext *context, lo_DocState *state )
|
||||
@ -1768,8 +1859,6 @@ void lo_rl_ReflowDocState( MWContext *context, lo_DocState *state )
|
||||
lo_RelayoutState *relay_state;
|
||||
LO_Element *first;
|
||||
|
||||
LO_LockLayout();
|
||||
|
||||
/* Create relayout state */
|
||||
relay_state = lo_rl_CreateRelayoutState();
|
||||
relay_state->doc_state = state;
|
||||
@ -1783,14 +1872,14 @@ void lo_rl_ReflowDocState( MWContext *context, lo_DocState *state )
|
||||
|
||||
/* Dummy Floating elements on a new line at the end of a document were not getting put into
|
||||
the line_array. This code should ensure that anything left on the line_list gets flushed
|
||||
to the line_array. */
|
||||
to the line_array. */
|
||||
/*
|
||||
if (state->line_list != NULL)
|
||||
lo_AppendLineListToLineArray( context, state, lo_GetLastElementInList(state->line_list) );
|
||||
*/
|
||||
|
||||
/* Done with relayout. Destroy relayout state. */
|
||||
lo_rl_DestroyRelayoutState( relay_state );
|
||||
|
||||
LO_UnlockLayout();
|
||||
}
|
||||
|
||||
void lo_PrepareElementForReuse( MWContext *context, lo_DocState *state, LO_Element * eptr,
|
||||
|
@ -229,30 +229,6 @@ lo_SetElementFGColor(LO_Element *element, LO_Color *color)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
lo_ShiftElementList(LO_Element *e_list, int32 dx, int32 dy)
|
||||
{
|
||||
LO_Element *eptr;
|
||||
|
||||
if (e_list == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
eptr = e_list;
|
||||
while (eptr != NULL)
|
||||
{
|
||||
eptr->lo_any.x += dx;
|
||||
eptr->lo_any.y += dy;
|
||||
if (eptr->type == LO_CELL)
|
||||
{
|
||||
lo_ShiftCell((LO_CellStruct *)eptr, dx, dy);
|
||||
}
|
||||
|
||||
eptr = eptr->lo_any.next;
|
||||
}
|
||||
}
|
||||
|
||||
NET_ReloadMethod
|
||||
LO_GetReloadMethod(MWContext *context)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user