/* * MapInfo.c -- MapInfo interface. * * Authors : Patrick Lecoanet. * Creation date : * * $Id$ */ /* * Copyright (c) 1993 - 1999 CENA, Patrick Lecoanet -- * * This code is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This code is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this code; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #include #include #include #include #include "MapInfo.h" #include #include #include #include #include #include #include static const char rcsid[] = "$Id$"; static const char compile_id[]="$Compile: " __FILE__ " " __DATE__ " " __TIME__ " $"; /* *----------------------------------------------------------------------- * * New types * *----------------------------------------------------------------------- */ typedef struct { ZnPtr tag; MapInfoLineStyle style; int width; MapInfoPointStruct center; unsigned int radius; int start_angle; int extend; } MapInfoArcStruct, *MapInfoArc; typedef struct { ZnPtr tag; MapInfoLineStyle style; int width; MapInfoPointStruct from; MapInfoPointStruct to; unsigned int num_marks; MapInfoPoint marks; } MapInfoLineStruct, *MapInfoLine; typedef struct { ZnPtr tag; MapInfoPointStruct at; char symbol[2]; } MapInfoSymbolStruct, *MapInfoSymbol; typedef struct { ZnPtr tag; MapInfoTextStyle text_style; MapInfoLineStyle line_style; MapInfoPointStruct at; char *text; } MapInfoTextStruct, *MapInfoText; typedef struct { char *name; ZnList lines; ZnList symbols; ZnList texts; ZnList arcs; } MapInfoStruct, *MapInfo; #define MARKERS_SPACING 80.0 /* 10 nautic miles in 1/8 of a mile */ #define BASE_ALLOC_SIZE 8 /* *----------------------------------------------------------------------- * * Macros. * *----------------------------------------------------------------------- */ #define NOT_MARKED_STYLE(style) \ ((style) == MapInfoLineMarked ? MapInfoLineSimple : (style)); /* *----------------------------------------------------------------------- * * ComputeLineMarks -- * Add marks to a line in the marks substructure. * *----------------------------------------------------------------------- */ static void ComputeLineMarks(MapInfoLine marked_line) { double length; unsigned int j; int x_from = marked_line->from.x; int y_from = marked_line->from.y; int x_to = marked_line->to.x; int y_to = marked_line->to.y; int delta_x = x_from - x_to; int delta_y = y_from - y_to; int step_x, step_y; length = sqrt((double)((delta_x) * (delta_x) + (delta_y) * (delta_y))); step_x = (int) ((x_to - x_from) * MARKERS_SPACING / length); step_y = (int) ((y_to - y_from) * MARKERS_SPACING / length); marked_line->num_marks = (int) length / MARKERS_SPACING; /* We don't want markers at ends, so we get rid of the last one if it is at an end */ if (fmod(length, MARKERS_SPACING) == 0.0) { (marked_line->num_marks)--; } if (marked_line->num_marks) { marked_line->marks = (MapInfoPoint) ZnMalloc(marked_line->num_marks * sizeof(MapInfoPointStruct)); } for (j = 0; j < marked_line->num_marks; j++) { marked_line->marks[j].x = x_from + ((j + 1) * step_x); marked_line->marks[j].y = y_from + ((j + 1) * step_y); } } MapInfoId MapInfoCreate(char *name) { MapInfo new_map; new_map = (MapInfo) ZnMalloc(sizeof(MapInfoStruct)); memset((char *) new_map, 0, sizeof(MapInfoStruct)); if (!name) { name = ""; } new_map->name = (char *) ZnMalloc(strlen(name)+1); strcpy(new_map->name, name); return((MapInfoId) new_map); } char * MapInfoName(MapInfoId map_info) { if (!map_info) { return ""; } return ((MapInfo) map_info)->name; } MapInfoId MapInfoDuplicate(MapInfoId map_info) { MapInfo cur_map = (MapInfo) map_info; MapInfo new_map; int i, num_lines, num_texts; MapInfoText new_texts, cur_texts; MapInfoLine new_lines, cur_lines; if (!cur_map) { return ((MapInfoId) NULL); } new_map = (MapInfo) MapInfoCreate(cur_map->name); if (cur_map->lines) { new_map->lines = ZnListDuplicate(cur_map->lines); cur_lines = (MapInfoLine) ZnListArray(cur_map->lines); new_lines = (MapInfoLine) ZnListArray(new_map->lines); num_lines = ZnListSize(cur_map->lines); for (i = 0; i < num_lines; i++) { if (new_lines[i].style == MapInfoLineMarked) { new_lines[i].marks = (MapInfoPoint) ZnMalloc(new_lines[i].num_marks * sizeof(MapInfoPointStruct)); memcpy((char *) new_lines[i].marks, (char *) cur_lines[i].marks, new_lines[i].num_marks * sizeof(MapInfoPointStruct)); } } } if (cur_map->symbols) { new_map->symbols = ZnListDuplicate(cur_map->symbols); } if (cur_map->texts) { new_map->texts = ZnListDuplicate(cur_map->texts); cur_texts = (MapInfoText) ZnListArray(cur_map->texts); new_texts = (MapInfoText) ZnListArray(new_map->texts); num_texts = ZnListSize(cur_map->texts); for (i = 0; i < num_texts; i++) { new_texts[i].text = (char *) ZnMalloc(strlen(cur_texts[i].text) + 1); strcpy(new_texts[i].text, cur_texts[i].text); } } if (cur_map->arcs) { new_map->arcs = ZnListDuplicate(cur_map->arcs); } return((MapInfoId) new_map); } void MapInfoDelete(MapInfoId map_info) { MapInfo cur_map = (MapInfo) map_info; int i, num_texts, num_lines; MapInfoText cur_texts; MapInfoLine cur_lines; if (cur_map) { if (cur_map->texts) { num_texts = ZnListSize(cur_map->texts); cur_texts = (MapInfoText) ZnListArray(cur_map->texts); for (i = 0; i < num_texts; i++) { ZnFree((char *) cur_texts[i].text); } ZnListFree(cur_map->texts); } if (cur_map->lines) { num_lines = ZnListSize(cur_map->lines); cur_lines = (MapInfoLine) ZnListArray(cur_map->lines); for (i = 0; i < num_lines; i++) { if (cur_lines[i].style == MapInfoLineMarked) { ZnFree((char *) cur_lines[i].marks); } } ZnListFree(cur_map->lines); } if (cur_map->symbols) { ZnListFree(cur_map->symbols); } if (cur_map->arcs) { ZnListFree(cur_map->arcs); } ZnFree(cur_map->name); ZnFree(cur_map); } } void MapInfoEmpty(MapInfoId map_info) { MapInfo cur_map = (MapInfo) map_info; if (cur_map) { if (cur_map->texts) { ZnListEmpty(cur_map->texts); } if (cur_map->lines) { ZnListEmpty(cur_map->lines); } if (cur_map->symbols) { ZnListEmpty(cur_map->symbols); } if (cur_map->arcs) { ZnListEmpty(cur_map->arcs); } } } void MapInfoAddLine(MapInfoId map_info, unsigned int index, ZnPtr tag, MapInfoLineStyle line_style, int line_width, int x_from, int y_from, int x_to, int y_to) { MapInfo cur_map = (MapInfo) map_info; MapInfoLineStruct line_struct; if (cur_map) { if (!cur_map->lines) { cur_map->lines = ZnListNew(16, sizeof(MapInfoLineStruct)); } line_struct.style = line_style; if (line_width == 1) { line_struct.width = 0; } else { line_struct.width = line_width; } line_struct.tag = tag; line_struct.from.x = x_from; line_struct.from.y = y_from; line_struct.to.x = x_to; line_struct.to.y = y_to; if (line_style == MapInfoLineMarked) { ComputeLineMarks(&line_struct); } ZnListAdd(cur_map->lines, &line_struct, index); } } void MapInfoReplaceLine(MapInfoId map_info, unsigned int index, ZnPtr tag, MapInfoLineStyle line_style, int line_width, int x_from, int y_from, int x_to, int y_to) { MapInfo cur_map = (MapInfo) map_info; MapInfoLine line_ptr; if (cur_map && cur_map->lines) { line_ptr = (MapInfoLine) ZnListAt(cur_map->lines, index); if (line_ptr) { if (line_ptr->style == MapInfoLineMarked) { ZnFree((char *) line_ptr->marks); } line_ptr->style = line_style; if (line_width == 1) { line_ptr->width = 0; } else { line_ptr->width = line_width; } line_ptr->tag = tag; line_ptr->from.x = x_from; line_ptr->from.y = y_from; line_ptr->to.x = x_to; line_ptr->to.y = y_to; if (line_ptr->style == MapInfoLineMarked) { ComputeLineMarks(line_ptr); } } } } void MapInfoRemoveLine(MapInfoId map_info, unsigned int index) { MapInfo cur_map = (MapInfo) map_info; MapInfoLine line_ptr; if (cur_map && cur_map->lines) { line_ptr = (MapInfoLine) ZnListAt(cur_map->lines, index); if (line_ptr) { if (line_ptr->style == MapInfoLineMarked) { ZnFree((char *) line_ptr->marks); } ZnListDelete(cur_map->lines, index); } } } void MapInfoGetLine(MapInfoId map_info, unsigned int index, ZnPtr *tag, MapInfoLineStyle *line_style, int *line_width, int *x_from, int *y_from, int *x_to, int *y_to) { MapInfo cur_map = (MapInfo) map_info; MapInfoLine line_ptr; if (cur_map && cur_map->lines) { line_ptr = (MapInfoLine) ZnListAt(cur_map->lines, index); if (line_ptr) { if (tag) { *tag = line_ptr->tag; } if (line_style) { *line_style = line_ptr->style; } if (line_width) { if (line_ptr->width == 1) { *line_width = 0; } else { *line_width = line_ptr->width; } } if (x_from) { *x_from = line_ptr->from.x; } if (y_from) { *y_from = line_ptr->from.y; } if (x_to) { *x_to = line_ptr->to.x; } if (y_to) { *y_to = line_ptr->to.y; } } } } void MapInfoGetMarks(MapInfoId map_info, unsigned int index, MapInfoPoint *marks, unsigned int *num_marks) { MapInfo cur_map = (MapInfo) map_info; MapInfoLine line_ptr; if (cur_map && cur_map->lines) { line_ptr = (MapInfoLine) ZnListAt(cur_map->lines, index); if (line_ptr && line_ptr->style == MapInfoLineMarked) { if (marks) { *marks = line_ptr->marks; } if (num_marks) { *num_marks = line_ptr->num_marks; } } } } unsigned int MapInfoNumLines(MapInfoId map_info) { MapInfo cur_map = (MapInfo) map_info; if (cur_map && cur_map->lines) { return ZnListSize(cur_map->lines); } else { return 0; } } void MapInfoAddSymbol(MapInfoId map_info, unsigned int index, ZnPtr tag, int x, int y, char symbol) { MapInfo cur_map = (MapInfo) map_info; MapInfoSymbolStruct symbol_struct; if (cur_map) { if (!cur_map->symbols) { cur_map->symbols = ZnListNew(16, sizeof(MapInfoSymbolStruct)); } symbol_struct.tag = tag; symbol_struct.at.x = x; symbol_struct.at.y = y; symbol_struct.symbol[0] = symbol; symbol_struct.symbol[1] = '\0'; ZnListAdd(cur_map->symbols, &symbol_struct, index); } } void MapInfoReplaceSymbol(MapInfoId map_info, unsigned int index, ZnPtr tag, int x, int y, char symbol) { MapInfo cur_map = (MapInfo) map_info; MapInfoSymbolStruct symbol_struct; if (cur_map && cur_map->symbols) { symbol_struct.tag = tag; symbol_struct.at.x = x; symbol_struct.at.y = y; symbol_struct.symbol[0] = symbol; symbol_struct.symbol[1] = '\0'; ZnListAtPut(cur_map->symbols, &symbol_struct, index); } } void MapInfoRemoveSymbol(MapInfoId map_info, unsigned int index) { MapInfo cur_map = (MapInfo) map_info; if (cur_map && cur_map->symbols) { ZnListDelete(cur_map->symbols, index); } } void MapInfoGetSymbol(MapInfoId map_info, unsigned int index, ZnPtr *tag, int *x, int *y, char *symbol) { MapInfo cur_map = (MapInfo) map_info; MapInfoSymbol symbol_ptr; if (cur_map && cur_map->symbols) { symbol_ptr = (MapInfoSymbol) ZnListAt(cur_map->symbols, index); if (symbol_ptr) { if (tag) { *tag = symbol_ptr->tag; } if (x) { *x = symbol_ptr->at.x; } if (y) { *y = symbol_ptr->at.y; } if (symbol) { *symbol = symbol_ptr->symbol[0]; } } } } unsigned int MapInfoNumSymbols(MapInfoId map_info) { MapInfo cur_map = (MapInfo) map_info; if (cur_map && cur_map->symbols) { return ZnListSize(cur_map->symbols); } else { return 0; } } void MapInfoAddText(MapInfoId map_info, unsigned int index, ZnPtr tag, MapInfoTextStyle text_style, MapInfoLineStyle line_style, int x, int y, char *text) { MapInfo cur_map = (MapInfo) map_info; MapInfoTextStruct text_struct; if (cur_map) { if (!cur_map->texts) { cur_map->texts = ZnListNew(16, sizeof(MapInfoTextStruct)); } text_struct.tag = tag; text_struct.text_style = text_style; text_struct.line_style = NOT_MARKED_STYLE(line_style); text_struct.at.x = x; text_struct.at.y = y; text_struct.text = (char *) ZnMalloc(strlen(text) + 1); strcpy(text_struct.text, text); ZnListAdd(cur_map->texts, &text_struct, index); } } void MapInfoReplaceText(MapInfoId map_info, unsigned int index, ZnPtr tag, MapInfoTextStyle text_style, MapInfoLineStyle line_style, int x, int y, char *text) { MapInfo cur_map = (MapInfo) map_info; MapInfoText text_ptr; if (cur_map && cur_map->texts) { text_ptr = (MapInfoText) ZnListAt(cur_map->texts, index); if (text_ptr) { ZnFree(text_ptr->text); text_ptr->tag = tag; text_ptr->text_style = text_style; text_ptr->line_style = NOT_MARKED_STYLE(line_style); text_ptr->at.x = x; text_ptr->at.y = y; text_ptr->text = (char *) ZnMalloc(strlen(text) + 1); strcpy(text_ptr->text, text); } } } void MapInfoRemoveText(MapInfoId map_info, unsigned int index) { MapInfo cur_map = (MapInfo) map_info; MapInfoText text_ptr; if (cur_map && cur_map->texts) { text_ptr = (MapInfoText) ZnListAt(cur_map->texts, index); if (text_ptr) { ZnFree(text_ptr->text); ZnListDelete(cur_map->texts, index); } } } void MapInfoGetText(MapInfoId map_info, unsigned int index, ZnPtr *tag, MapInfoTextStyle *text_style, MapInfoLineStyle *line_style, int *x, int *y, char **text) { MapInfo cur_map = (MapInfo) map_info; MapInfoText text_ptr; if (cur_map && cur_map->texts) { text_ptr = (MapInfoText) ZnListAt(cur_map->texts, index); if (text_ptr) { if (tag) { *tag = text_ptr->tag; } if (text_style) { *text_style = text_ptr->text_style; } if (line_style) { *line_style = text_ptr->line_style; } if (x) { *x = text_ptr->at.x; } if (y) { *y = text_ptr->at.y; } if (text) { *text = text_ptr->text; } } } } unsigned int MapInfoNumTexts(MapInfoId map_info) { MapInfo cur_map = (MapInfo) map_info; if (cur_map && cur_map->texts) { return ZnListSize(cur_map->texts); } else { return 0; } } void MapInfoAddArc(MapInfoId map_info, unsigned int index, ZnPtr tag, MapInfoLineStyle line_style, int line_width, int center_x, int center_y, unsigned int radius, int start_angle, int extend) { MapInfo cur_map = (MapInfo) map_info; MapInfoArcStruct arc_struct; if (cur_map) { if (!cur_map->arcs) { cur_map->arcs = ZnListNew(16, sizeof(MapInfoArcStruct)); } arc_struct.style = NOT_MARKED_STYLE(line_style); if (line_width == 1) { arc_struct.width = 0; } else { arc_struct.width = line_width; } arc_struct.tag = tag; arc_struct.center.x = center_x; arc_struct.center.y = center_y; arc_struct.radius = radius; arc_struct.start_angle = start_angle; arc_struct.extend = extend; ZnListAdd(cur_map->arcs, &arc_struct, index); } } void MapInfoReplaceArc(MapInfoId map_info, unsigned int index, ZnPtr tag, MapInfoLineStyle line_style, int line_width, int center_x, int center_y, unsigned int radius, int start_angle, int extend) { MapInfo cur_map = (MapInfo) map_info; MapInfoArc arc_ptr; if (cur_map && cur_map->arcs) { arc_ptr = (MapInfoArc) ZnListAt(cur_map->arcs, index); if (arc_ptr) { arc_ptr->style = NOT_MARKED_STYLE(line_style); if (line_width == 1) { arc_ptr->width = 0; } else { arc_ptr->width = line_width; } arc_ptr->tag = tag; arc_ptr->center.x = center_x; arc_ptr->center.y = center_y; arc_ptr->radius = radius; arc_ptr->start_angle = start_angle; arc_ptr->extend = extend; } } } void MapInfoRemoveArc(MapInfoId map_info, unsigned int index) { MapInfo cur_map = (MapInfo) map_info; MapInfoArc arc_ptr; if (cur_map && cur_map->arcs) { arc_ptr = (MapInfoArc) ZnListAt(cur_map->arcs, index); if (arc_ptr) { ZnListDelete(cur_map->arcs, index); } } } void MapInfoGetArc(MapInfoId map_info, unsigned int index, ZnPtr *tag, MapInfoLineStyle *line_style, int *line_width, int *center_x, int *center_y, unsigned int *radius, int *start_angle, int *extend) { MapInfo cur_map = (MapInfo) map_info; MapInfoArc arc_ptr; if (cur_map && cur_map->arcs) { arc_ptr = (MapInfoArc) ZnListAt(cur_map->arcs, index); if (arc_ptr) { if (tag) { *tag = arc_ptr->tag; } if (line_style) { *line_style = arc_ptr->style; } if (line_width) { if (arc_ptr->width == 1) { *line_width = 0; } else { *line_width = arc_ptr->width; } } if (center_x) { *center_x = arc_ptr->center.x; } if (center_y) { *center_y = arc_ptr->center.y; } if (radius) { *radius = arc_ptr->radius; } if (start_angle) { *start_angle = arc_ptr->start_angle; } if (extend) { *extend = arc_ptr->extend; } } } } unsigned int MapInfoNumArcs(MapInfoId map_info) { MapInfo cur_map = (MapInfo) map_info; if (cur_map && cur_map->arcs) { return ZnListSize(cur_map->arcs); } else { return 0; } } void MapInfoScale(MapInfoId map_info, double factor) { MapInfo mp = (MapInfo) map_info; int i, num; MapInfoLine line_ptr; MapInfoSymbol sym_ptr; MapInfoText text_ptr; MapInfoArc arc_ptr; if (mp && mp->lines) { num = ZnListSize(mp->lines); line_ptr = (MapInfoLine) ZnListArray(mp->lines); for (i = 0; i < num; i++, line_ptr++) { line_ptr->from.x *= factor; line_ptr->from.y *= factor; line_ptr->to.x *= factor; line_ptr->to.y *= factor; } } if (mp && mp->symbols) { num = ZnListSize(mp->symbols); sym_ptr = (MapInfoSymbol) ZnListArray(mp->symbols); for (i = 0; i < num; i++, sym_ptr++) { sym_ptr->at.x *= factor; sym_ptr->at.y *= factor; } } if (mp && mp->texts) { num = ZnListSize(mp->texts); text_ptr = (MapInfoText) ZnListArray(mp->texts); for (i = 0; i < num; i++, text_ptr++) { text_ptr->at.x *= factor; text_ptr->at.y *= factor; } } if (mp && mp->arcs) { num = ZnListSize(mp->arcs); arc_ptr = (MapInfoArc) ZnListArray(mp->arcs); for (i = 0; i < num; i++, arc_ptr++) { arc_ptr->center.x *= factor; arc_ptr->center.y *= factor; arc_ptr->radius *= factor; } } } void MapInfoTranslate(MapInfoId map_info, int x, int y) { MapInfo mp = (MapInfo) map_info; int i, num; MapInfoLine line_ptr; MapInfoSymbol sym_ptr; MapInfoText text_ptr; MapInfoArc arc_ptr; if (mp && mp->lines) { num = ZnListSize(mp->lines); line_ptr = (MapInfoLine) ZnListArray(mp->lines); for (i = 0; i < num; i++, line_ptr++) { line_ptr->from.x += x; line_ptr->from.y += y; line_ptr->to.x += x; line_ptr->to.y += y; } } if (mp && mp->symbols) { num = ZnListSize(mp->symbols); sym_ptr = (MapInfoSymbol) ZnListArray(mp->symbols); for (i = 0; i < num; i++, sym_ptr++) { sym_ptr->at.x += x; sym_ptr->at.y += y; } } if (mp && mp->texts) { num = ZnListSize(mp->texts); text_ptr = (MapInfoText) ZnListArray(mp->texts); for (i = 0; i < num; i++, text_ptr++) { text_ptr->at.x += x; text_ptr->at.y += y; } } if (mp && mp->arcs) { num = ZnListSize(mp->arcs); arc_ptr = (MapInfoArc) ZnListArray(mp->arcs); for (i = 0; i < num; i++, arc_ptr++) { arc_ptr->center.x += x; arc_ptr->center.y += y; } } } #define TEXT_SIZE 256 #define ntohi(n) ntohl((n)) /* *----------------------------------------------------------------------- * * Videomap record definition. Ints are assumed to be 4 bytes. * *----------------------------------------------------------------------- */ typedef struct { int id; /* Map id (internal) */ int dashed; /* Tell if vectors are dashed (exclusive with marked) */ int expanded; /* Device coordinates or world coordinates (ignored now) */ int marked; /* Tell if vectors are marked (exclusive with dashed) */ int color; /* drawing color (ignored now) */ int elements[50]; /* Element type ('P', 'V', 'T') */ int x[50]; /* Coordinates if 'P' or 'V' */ int y[50]; int symbol[50]; /* Filled if 'P' or 'V' */ int text[50]; /* Low order byte is ascii char if 'T' */ int num_elements; /* Number of elements */ } VideoMap; /* *----------------------------------------------------------------------- * * ReorderVidomap - reorder integers according to the endianess * *----------------------------------------------------------------------- */ static void ReorderVidomap(VideoMap *vm) { int loop; vm->id = ntohi(vm->id); vm->dashed = ntohi(vm->dashed); vm->expanded = ntohi(vm->expanded); vm->marked = ntohi(vm->marked); vm->color = ntohi(vm->color); for (loop = 0; loop < 50; loop++) { vm->elements[loop] = ntohi(vm->elements[loop]); vm->x[loop] = ntohi(vm->x[loop]); vm->y[loop] = ntohi(vm->y[loop]); vm->symbol[loop] = ntohi(vm->symbol[loop]); vm->text[loop] = ntohi(vm->text[loop]); } vm->num_elements = ntohi(vm->num_elements); } /* *----------------------------------------------------------------------- * * FillMap - Fill map with data in Videomap record vm. * *----------------------------------------------------------------------- */ static void FillMap(MapInfoId map, VideoMap *vm) { unsigned int i; ZnBool has_start_pos = False; int x_cur=0, y_cur=0; char ch; int text_x=0, text_y=0; char text[TEXT_SIZE]; ZnBool in_text = False; ZnBool in_mod_text = False; unsigned int text_size=0; for (i = 0; i < vm->num_elements; i++) { switch(vm->elements[i] & 0xFF) { case 'p': case 'P': if (in_text) { in_text = in_mod_text = False; while (text[text_size - 1] == ' ') { text_size--; } text[text_size] = (char) 0; MapInfoAddText(map, MapInfoNumTexts(map), NULL, MapInfoNormalText, MapInfoLineSimple, text_x, text_y, text); } x_cur = (int) (short) vm->x[i]; y_cur = (int) (short) vm->y[i]; has_start_pos = True; if (vm->symbol[i]) { MapInfoAddSymbol(map, MapInfoNumSymbols(map), NULL, x_cur, y_cur, vm->symbol[i]); } break; /* We gather consecutive 'T' elements in a text. We skip leading and trailing spaces and mod texts (between '@' and now obsolete) */ case 't': case 'T': if (!has_start_pos) { ZnWarning("Bloc carte incorrect, il est elimine"); return; } if (in_text == False) { ch = (char) vm->text[i] & 0xFF; if (ch == '@') { if (in_mod_text == True) { in_mod_text = False; } else { in_mod_text = True; } } else if (in_mod_text == False) { in_text = True; text_size = 0; text_x = x_cur; text_y = y_cur; text[0] = (char) 0; } } if (in_text) { text[text_size] = (char) vm->text[i] & 0xFF; text_size++; } break; case 'v': case 'V': if (!has_start_pos) { ZnWarning("Bloc carte incorrect, il est elimine"); return; } if (in_text) { in_text = in_mod_text = False; while (text[text_size - 1] == ' ') { text_size--; } text[text_size] = (char) 0; MapInfoAddText(map, MapInfoNumTexts(map), NULL, MapInfoNormalText, MapInfoLineSimple, text_x, text_y, text); } if (vm->dashed) { MapInfoAddLine(map, MapInfoNumLines(map), NULL, MapInfoLineDashed, 0, x_cur, y_cur, (int) (short) vm->x[i], (int) (short) vm->y[i]); } else if (vm->marked) { MapInfoAddLine(map, MapInfoNumLines(map), NULL, MapInfoLineMarked, 0, x_cur, y_cur, (int) (short) vm->x[i], (int) (short) vm->y[i]); } else { MapInfoAddLine(map, MapInfoNumLines(map), NULL, MapInfoLineSimple, 0, x_cur, y_cur, (int) (short) vm->x[i], (int) (short) vm->y[i]); } x_cur = (int) (short) vm->x[i]; y_cur = (int) (short) vm->y[i]; if (vm->symbol[i]) { MapInfoAddSymbol(map, MapInfoNumSymbols(map), NULL, x_cur, y_cur, vm->symbol[i]); } break; } } if (in_text) { in_text = in_mod_text = False; while (text[text_size - 1] == ' ') { text_size--; } text[text_size] = (char) 0; MapInfoAddText(map, MapInfoNumTexts(map), NULL, MapInfoNormalText, MapInfoLineSimple, text_x, text_y, text); } } /* *----------------------------------------------------------------------- * * MapInfoGetVideomap - Load a mapinfo with the content of a videomap * file named 'filename'. Only the sub map 'index' will be loaded. * If successful a new mapinfo is returned, NULL otherwise. The * index is zero based. * *----------------------------------------------------------------------- */ int MapInfoGetVideomap(MapInfoId map, char *filename, int index) { VideoMap current_vm; FILE *file; int cur_index, cur_id; /* Open the specified map file. */ file = fopen(filename, "r"); if (file == NULL) { return ZN_ERROR; } /* Load the map */ /* First skip the leading maps up to index. */ cur_index = 0; if (fread(¤t_vm, sizeof(VideoMap), 1, file) < 0) { goto error; } cur_id = ntohi(current_vm.id); while (cur_index != index) { if (fread(¤t_vm, sizeof(VideoMap), 1, file) < 0) { goto error; } if (cur_id != ntohi(current_vm.id)) { cur_index++; cur_id = ntohi(current_vm.id); } }; /* Then load all the map modules. */ do { ReorderVidomap(¤t_vm); FillMap(map, ¤t_vm); if ((fread(¤t_vm, sizeof(VideoMap), 1, file) != 1) && !feof(file)) { goto error; } } while ((cur_id == ntohi(current_vm.id)) && !feof(file)); fclose(file); return ZN_OK; error: fclose(file); return ZN_ERROR; } /* *----------------------------------------------------------------------- * * MapInfoVideomapIds - Return the list of sub map ids contained in a * videomap file. This makes it possible to iterate through such * a file without stumbling on an error, to know how much maps * are there and to sort them according to their ids. * *----------------------------------------------------------------------- */ ZnList MapInfoVideomapIds(char *filename) { FILE *file; VideoMap current_vm; int cur_id; ZnList ids; /* Open the specified map file. */ file = fopen(filename, "r"); if (file == NULL) { return NULL; } if (fread(¤t_vm, sizeof(VideoMap), 1, file) < 0) { goto error; } cur_id = ntohi(current_vm.id); ids = ZnListNew(16, sizeof(int)); /*printf("id %d\n", cur_id);*/ ZnListAdd(ids, &cur_id, ZnListTail); do { if (fread(¤t_vm, sizeof(VideoMap), 1, file) < 0) { goto error; } if (cur_id != ntohi(current_vm.id)) { cur_id = ntohi(current_vm.id); /*printf("id %d\n", cur_id);*/ ZnListAdd(ids, &cur_id, ZnListTail); } } while (!feof(file)); fclose(file); return ids; error: fclose(file); ZnListFree(ids); return NULL; }