/************************************* * Function: pa_CloneMDLTag * * Description: This function allocates and fills in an entire * PA_Tag structure for any MDL tag element type. * * Params: The tag to clone * * Returns: A pointer to a completely filled in PA_Tag structure * that is a clone of the tag passed in. On failure it * returns NULL. *************************************/ PA_Tag * PA_CloneMDLTag(PA_Tag * src) { PA_Tag *tag; PA_Block buff; char *locked_buff, *src_buff; /* * Allocate a new tag structure, return NULL * if you can't. */ tag = XP_NEW(PA_Tag); if (tag == NULL) { return(NULL); } tag->type = src->type; tag->is_end = src->is_end; tag->newline_count = src->newline_count; tag->data_len = src->data_len; tag->true_len = src->true_len; tag->lo_data = NULL; tag->next = NULL; /* sure wish we could just do a strdup() here */ buff = PA_ALLOC((tag->data_len + 1) * sizeof(char)); if (buff != NULL) { PA_LOCK(locked_buff, char *, buff); PA_LOCK(src_buff, char *, src->data); XP_BCOPY(src_buff, locked_buff, tag->data_len); locked_buff[tag->data_len] = '\0'; PA_UNLOCK(locked_buff); PA_UNLOCK(src_buff); }
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; tmp_text.text_attr = state->font_stack->text_attr; 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; }
/* * This is an AREA tag. Create the structure, fill it in based on the * attributes passed, and add it to the map record for the current * MAP tag. */ void lo_BeginMapArea(MWContext *context, lo_DocState *state, PA_Tag *tag) { PA_Block buff; char *str; lo_MapRec *map; lo_MapAreaRec *area; lo_DocLists *doc_lists; doc_lists = lo_GetCurrentDocLists(state); /* * Get the current map, if there is none, error out. */ map = state->top_state->current_map; if (map == NULL) { return; } area = XP_NEW(lo_MapAreaRec); if (area == NULL) { state->top_state->out_of_memory = TRUE; return; } area->type = AREA_SHAPE_RECT; area->coords = NULL; area->coord_cnt = 0; area->anchor = NULL; area->alt = NULL; area->alt_len = 0; area->next = NULL; buff = lo_FetchParamValue(context, tag, PARAM_SHAPE); if (buff != NULL) { PA_LOCK(str, char *, buff); if (pa_TagEqual(S_AREA_SHAPE_RECT, str)) { area->type = AREA_SHAPE_RECT; } else if (pa_TagEqual(S_AREA_SHAPE_CIRCLE, str)) { area->type = AREA_SHAPE_CIRCLE; } else if (pa_TagEqual(S_AREA_SHAPE_POLY, str)) { area->type = AREA_SHAPE_POLY; } else if (pa_TagEqual(S_AREA_SHAPE_POLYGON, str)) { area->type = AREA_SHAPE_POLY; } else if (pa_TagEqual(S_AREA_SHAPE_DEFAULT, str)) { area->type = AREA_SHAPE_DEFAULT; } else { area->type = AREA_SHAPE_UNKNOWN; } PA_UNLOCK(buff); PA_FREE(buff); } /* * Get the alt parameter, and store the resulting * text, and its length. */ buff = lo_FetchParamValue(context, tag, PARAM_ALT); if (buff != NULL) { PA_LOCK(str, char *, buff); area->alt_len = XP_STRLEN(str); area->alt_len = (int16)lo_StripTextNewlines(str, (int32)area->alt_len); PA_UNLOCK(buff); } area->alt = buff; /* * Parse the comma separated coordinate list into an * array of integers. */ buff = lo_FetchParamValue(context, tag, PARAM_COORDS); if (buff != NULL) { int32 cnt; Bool must_be_odd; must_be_odd = FALSE; if (area->type == AREA_SHAPE_POLY) { must_be_odd = TRUE; } PA_LOCK(str, char *, buff); area->coords = lo_parse_coord_list(str, &cnt, must_be_odd); if (area->coords != NULL) { area->coord_cnt = cnt; } PA_UNLOCK(buff); PA_FREE(buff); } /* * Get the HREF, and if one exists, get the TARGET to go along * with it. */ buff = lo_FetchParamValue(context, tag, PARAM_HREF); if (buff != NULL) { char *target; PA_Block targ_buff; PA_Block href_buff; LO_AnchorData *anchor; anchor = NULL; PA_LOCK(str, char *, buff); if (str != NULL) { int32 len; len = lo_StripTextWhitespace(str, XP_STRLEN(str)); } str = NET_MakeAbsoluteURL(state->top_state->base_url, str); if (str == NULL) { href_buff = NULL; } else { href_buff = PA_ALLOC(XP_STRLEN(str) + 1); if (href_buff != NULL) { char *full_url; PA_LOCK(full_url, char *, href_buff); XP_STRCPY(full_url, str); PA_UNLOCK(href_buff); } else { state->top_state->out_of_memory = TRUE; } XP_FREE(str); } PA_UNLOCK(buff); PA_FREE(buff); if (href_buff != NULL) { targ_buff = lo_FetchParamValue(context, tag, PARAM_TARGET); if (targ_buff != NULL) { int32 len; PA_LOCK(target, char *, targ_buff); len = lo_StripTextWhitespace(target, XP_STRLEN(target)); if ((*target == '\0')|| (lo_IsValidTarget(target) == FALSE)) { PA_UNLOCK(targ_buff); PA_FREE(targ_buff); targ_buff = NULL; } else { PA_UNLOCK(targ_buff); } } /* * If there was no target use the default one. * (default provided by BASE tag) */ if ((targ_buff == NULL)&& (state->top_state->base_target != NULL)) { targ_buff = PA_ALLOC(XP_STRLEN( state->top_state->base_target) + 1); if (targ_buff != NULL) { char *targ; PA_LOCK(targ, char *, targ_buff); XP_STRCPY(targ, state->top_state->base_target); PA_UNLOCK(targ_buff); } else { state->top_state->out_of_memory = TRUE; } } anchor = lo_NewAnchor(state, href_buff, targ_buff); if (anchor == NULL) { PA_FREE(href_buff); if (targ_buff != NULL) { PA_FREE(targ_buff); } } /* * If the AREA tag has an ALT attribute, * stick that text into the anchor data. */ else if (area->alt != NULL) { PA_Block alt_buff; char *alt_text; PA_LOCK(alt_text, char *, area->alt); alt_buff = PA_ALLOC(area->alt_len + 1); if (alt_buff != NULL) { char *new_alt; PA_LOCK(new_alt, char *, alt_buff); XP_STRCPY(new_alt, alt_text); PA_UNLOCK(alt_buff); } PA_UNLOCK(area->alt); anchor->alt = alt_buff; }
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); }
lo_ObjectStack* lo_PushObject(MWContext* context, lo_DocState* state, PA_Tag* tag) { /* * If possible, reuse an object stack entry created in * a previous pass over this tag (i.e. while blocked, by * lo_BlockObjectTag). If there's no previously-created * object, make a new one. */ lo_TopState* top_state = state->top_state; lo_ObjectStack* new_top = top_state->object_cache; if (new_top != NULL) { /* Find and remove the matching item, if any */ if (new_top->real_tag == tag) top_state->object_cache = new_top->next; else { while (new_top->next != NULL) { if (new_top->next->real_tag == tag) { lo_ObjectStack* temp = new_top->next; new_top->next = new_top->next->next; new_top = temp; break; } new_top = new_top->next; } } } if (new_top == NULL || new_top->real_tag != tag) { new_top = XP_NEW_ZAP(lo_ObjectStack); if (new_top == NULL) { state->top_state->out_of_memory = TRUE; return NULL; } } new_top->next = top_state->object_stack; top_state->object_stack = new_top; new_top->context = context; new_top->state = state; /* * Clone the tag since the tag passed in may be freed * by the parser before we're ready for it. */ if (new_top->real_tag != tag) { new_top->real_tag = tag; if (new_top->clone_tag != NULL) PA_FreeTag(new_top->clone_tag); new_top->clone_tag = XP_NEW(PA_Tag); if (new_top->clone_tag != NULL) { XP_MEMCPY(new_top->clone_tag, tag, sizeof(PA_Tag)); new_top->clone_tag->data = PA_ALLOC((tag->data_len + 1) * sizeof (char)); if (new_top->clone_tag->data != NULL) { char* source; char* dest; PA_LOCK(source, char*, tag->data); PA_LOCK(dest, char*, new_top->clone_tag->data); XP_MEMCPY(dest, source, tag->data_len + 1); PA_UNLOCK(dest); PA_UNLOCK(source); }
PA_Block lo_ValueToAlpha(int32 value, Bool large, intn *len_ptr) { int i; char str[20]; char str2[22]; intn pos, cnt; PA_Block buff; char *bptr; char base; *len_ptr = 0; if (large != FALSE) { base = 'A'; } else { base = 'a'; } for (i=0; i<20; i++) { str[i] = (char)0; } while (value > 26) { pos = 1; str[pos] = (char)((int)str[pos] + 1); cnt = (int)str[pos]; while ((cnt > 26)&&(pos < 19)) { str[pos] = (char)0; pos++; str[pos] = (char)((int)str[pos] + 1); cnt = (int)str[pos]; } if ((pos == 20)&&(cnt > 26)) { str[pos] = (char)0; } value -= 26; } str[0] = (char)value; pos = 0; while ((int)str[pos] != 0) { pos++; } if (pos == 0) { XP_STRCPY(str2, " ."); } else { cnt = 0; for (i=pos; i>0; i--) { str2[cnt] = (char)(base + (int)str[i - 1] - 1); cnt++; } str2[cnt] = '.'; str2[cnt + 1] = '\0'; } *len_ptr = XP_STRLEN(str2); buff = PA_ALLOC(*len_ptr + 1); if (buff != NULL) { PA_LOCK(bptr, char *, buff); XP_STRCPY(bptr, str2); PA_UNLOCK(buff); } return(buff); }
PA_Block lo_ValueToRoman(int32 value, Bool large, intn *len_ptr) { int i, j; int indx[4]; char str[4][6]; char *fives; char *ones; char str2[22]; char *ptr; PA_Block buff; char *bptr; *len_ptr = 0; if (large != FALSE) { fives = Fives[1]; ones = Ones[1]; } else { fives = Fives[0]; ones = Ones[0]; } if (value >= 4000) { value = value % 3999; value++; } for (i=0; i<4; i++) { indx[i] = (int) value % 10; value = value / 10; } for (i=0; i<4; i++) { if (indx[i] >= 5) { indx[i] -= 5; str[i][0] = fives[i]; } else { str[i][0] = ' '; } if (indx[i] == 4) { if (str[i][0] == ' ') { str[i][1] = fives[i]; } else { str[i][1] = ones[i + 1]; } str[i][0] = ones[i]; str[i][2] = '\0'; } else { for (j=0; j<indx[i]; j++) { str[i][j + 1] = ones[i]; } str[i][indx[i] + 1] = '\0'; } } XP_STRCPY(str2, ""); for (i=3; i>=0; i--) { ptr = str[i]; if (*ptr == ' ') { ptr++; } XP_STRCAT(str2, ptr); } XP_STRCAT(str2, "."); *len_ptr = XP_STRLEN(str2); buff = PA_ALLOC(*len_ptr + 1); if (buff != NULL) { PA_LOCK(bptr, char *, buff); XP_STRCPY(bptr, str2); PA_UNLOCK(buff); } return(buff); }