#include "dprmdoc.h" #include #include #include #include "alpo.h" #include "nrautil.h" struct { unsigned char drawparm_hdr[DPARM_HDR_SIZE]; unsigned short size_layer; unsigned short size_sym; unsigned short size_esym; unsigned short size_pset; unsigned short size_cpalt; unsigned short size_tpalt; unsigned short size_lpalt; unsigned short num_layer; unsigned short num_sym; unsigned short num_esym; unsigned short num_pset; unsigned short num_cpalt; unsigned short num_tpalt; unsigned short num_lpalt; unsigned char *popttl; unsigned char *pslut; unsigned char *peslut; unsigned char *ppset; unsigned char *pclut; unsigned char *ptlut; unsigned char *pllut; } m_drawparm; /*/////////////////////////////////////////////////////////////////////////// // CDprmDoc // ///////////////////////////////////////////////////////////////////////////// */ /* ParseHdr() // // Perform appropriate unsigned char swapping while parsing the drawparm header to // fill out the m_drawparm structure. */ /**/ BOOL ParseHdr(FILE* dpFile) { m_drawparm.size_layer = GET_NRA_SHORT(&m_drawparm.drawparm_hdr[4]); m_drawparm.size_sym = GET_NRA_SHORT(&m_drawparm.drawparm_hdr[10]); m_drawparm.size_esym = GET_NRA_SHORT(&m_drawparm.drawparm_hdr[16]); m_drawparm.size_pset = GET_NRA_SHORT(&m_drawparm.drawparm_hdr[22]); m_drawparm.size_cpalt = GET_NRA_SHORT(&m_drawparm.drawparm_hdr[28]); m_drawparm.size_tpalt = GET_NRA_SHORT(&m_drawparm.drawparm_hdr[34]); m_drawparm.size_lpalt = GET_NRA_SHORT(&m_drawparm.drawparm_hdr[40]); m_drawparm.popttl = (unsigned char*)malloc(m_drawparm.size_layer); if (!m_drawparm.popttl) return 0; fseek(dpFile, (long) GET_NRA_SHORT(m_drawparm.drawparm_hdr + 0), 0); fread( m_drawparm.popttl, 1, m_drawparm.size_layer, dpFile); m_drawparm.num_layer = GET_NRA_UCHAR(m_drawparm.drawparm_hdr + 3); m_drawparm.pslut = (unsigned char*)malloc(m_drawparm.size_sym); if (!m_drawparm.pslut) return 0; fseek(dpFile, (long) GET_NRA_SHORT(m_drawparm.drawparm_hdr + 6), 0); fread( m_drawparm.pslut, 1, m_drawparm.size_sym, dpFile); m_drawparm.num_sym = GET_NRA_SHORT(m_drawparm.drawparm_hdr + 8); m_drawparm.peslut = (unsigned char*)malloc(m_drawparm.size_esym); if (!m_drawparm.peslut) return 0; fseek(dpFile, (long) GET_NRA_SHORT(m_drawparm.drawparm_hdr + 12), 0); fread( m_drawparm.peslut, 1, m_drawparm.size_esym, dpFile); m_drawparm.num_esym = GET_NRA_SHORT(m_drawparm.drawparm_hdr + 14); m_drawparm.ppset = (unsigned char*)malloc(m_drawparm.size_pset); if (!m_drawparm.ppset) return 0; fseek(dpFile, (long) GET_NRA_SHORT(m_drawparm.drawparm_hdr + 18), 0); fread( m_drawparm.ppset, 1, m_drawparm.size_pset, dpFile); m_drawparm.num_pset = GET_NRA_UCHAR(m_drawparm.drawparm_hdr + 21); m_drawparm.pclut = (unsigned char*)malloc(m_drawparm.size_cpalt); if (!m_drawparm.pclut) return 0; fseek(dpFile, (long) GET_NRA_SHORT(m_drawparm.drawparm_hdr + 24), 0); fread( m_drawparm.pclut, 1, m_drawparm.size_cpalt, dpFile); m_drawparm.num_cpalt = GET_NRA_UCHAR(m_drawparm.drawparm_hdr + 27); m_drawparm.ptlut = (unsigned char*)malloc(m_drawparm.size_tpalt); if (!m_drawparm.ptlut) return 0; fseek(dpFile, (long) GET_NRA_SHORT(m_drawparm.drawparm_hdr + 30), 0); fread( m_drawparm.ptlut, 1, m_drawparm.size_tpalt, dpFile); m_drawparm.num_tpalt = GET_NRA_UCHAR(m_drawparm.drawparm_hdr + 33); m_drawparm.pllut = (unsigned char*)malloc(m_drawparm.size_lpalt); if (!m_drawparm.pllut) return 0; fseek(dpFile, (long) GET_NRA_SHORT(m_drawparm.drawparm_hdr + 36), 0); fread( m_drawparm.pllut, 1, m_drawparm.size_lpalt, dpFile); m_drawparm.num_lpalt = GET_NRA_UCHAR(m_drawparm.drawparm_hdr + 39); return 1; } void FreeBuffers() { if(m_drawparm.popttl) free(m_drawparm.popttl); if(m_drawparm.pslut) free(m_drawparm.pslut); if(m_drawparm.peslut) free(m_drawparm.peslut); if(m_drawparm.ppset) free(m_drawparm.ppset); if(m_drawparm.pclut) free(m_drawparm.pclut); if(m_drawparm.ptlut) free(m_drawparm.ptlut); if(m_drawparm.pllut) free(m_drawparm.pllut); memset ((void *)&m_drawparm, 0, sizeof (m_drawparm)); } BOOL ReadDpmFile(FILE* dpFile) { fseek(dpFile, 0L, 0); if (fread(m_drawparm.drawparm_hdr,1,DPARM_HDR_SIZE,dpFile) < DPARM_HDR_SIZE) return 0; /* figure out where option layers, palettes, etc. are; malloc the space // and read them in. */ return (ParseHdr(dpFile)); } /**/ BOOL OnOpenDocument(char* pszPathName) { FILE* dpFile; if (!(dpFile = nraOpen((char *)pszPathName, ".dpm", "rb"))) { return (0); } if (ReadDpmFile(dpFile) == 0) { FreeBuffers(); return 0; } fclose(dpFile); return 1; } /***** Vection Icon Cache Function Prototypes *******/ static void InitViconCache(void); static void FreeViconCache(void); /****************************************************/ /* CDprmDoc construction/destruction */ BOOL DprmDoc(char* pszPathName) { InitViconCache(); return OnOpenDocument(pszPathName); } void DprmDocDestroy() { FreeBuffers(); FreeViconCache(); } /*/////////////////////////////////////////////////////////////////////////// */ void LoadColEntry(ColorPalette *pPal, unsigned char* pclut, unsigned short num_cpalt) { unsigned short i; struct nra_colors *pcolors = (struct nra_colors *)(pclut + (sizeof(struct cpalt_dat) * num_cpalt)); for (i=0; i<16; i++) { pPal->rgb888[i].red = NRA_TO_TRUE_COLOR((pcolors->red)&0x0f); pPal->rgb888[i].green = NRA_TO_TRUE_COLOR( ((int)(pcolors->green_blue)&0x00f0)>>4 ); pPal->rgb888[i].blue = NRA_TO_TRUE_COLOR((pcolors->green_blue)&0x0f); pcolors++; } } /*/////////////////////////////////////////////////////////////////////////// */ LineStyle LoadLineEntry(unsigned char* pllut, unsigned short num_lpalt, unsigned short num_lstyle) { struct lpalt_dat *pLP = (struct lpalt_dat*)(pllut + (sizeof(struct lpalt_dat) * num_lpalt)); LineStyle style; style = GET_NRA_SHORT(&pLP->lpalt_pat[num_lstyle]); return style; } /*/////////////////////////////////////////////////////////////////////////// */ void LoadTextureEntry(TextureStyle* pTexture, unsigned char* ptlut, unsigned short num_tpalt, unsigned short num_tstyle) { int i; struct tpalt_dat *pTP = (struct tpalt_dat*)(ptlut + (sizeof(struct tpalt_dat) * num_tpalt)); for (i=0; i<8; i++) { pTexture->dotMap8[i] = pTP->tpalt_pat[num_tstyle].tpat_bytes[i]; } } /*/////////////////////////////////////////////////////////////////////////// */ /* Function returns FALSE if no match found; else TRUE and pBitMap filled in */ BOOL LoadSymbolEntry(SymBitMap* pBitMap, unsigned char* pslut, unsigned short symCode) { int i; int sym; unsigned short targetSym; struct sym_dat* pSymTab = (struct sym_dat*)pslut;; for (sym=0; sym<(int)m_drawparm.num_sym; sym++) { targetSym = GET_NRA_SHORT(&pSymTab->sym_code); printf("%x\n",targetSym); if (targetSym == symCode) { /* Found sym, retrieve bitmap and return TRUE */ for (i=0; i<16; i++) { pBitMap->dotSym16[i] = GET_NRA_SHORT(&pSymTab->sym_pattern[i]); } return 1; } pSymTab++; } return 0; } /*/////////////////////////////////////////////////////////////////////////// */ /* Function returns NULL ptr if no match found */ struct asym_dat* SearchESymbolEntry(unsigned char* peslut, unsigned short eSymCode) { int eSym; unsigned short targetESym; struct asym_dat* pAsymDat = (struct asym_dat*)0; struct esym_dat* pESymTab = (struct esym_dat*)peslut; for (eSym=0; eSym<(int)m_drawparm.num_esym; eSym++) { targetESym = GET_NRA_SHORT(&pESymTab->esym_code); if (targetESym == eSymCode) { /* Found eSym, compute and return ptr to found eSym's record */ pAsymDat = (struct asym_dat*)(peslut + GET_NRA_SHORT(&pESymTab->esym_off)); break; } pESymTab++; } return pAsymDat; } /*/////////////////////////////////////////////////////////////////////////// */ BOOL getNextSym(GetSymControlBlock* pCB) { struct bsym_dat* p; if (pCB->control.aSymMax == 0) { /* beginning of a series, return the base symbol now */ p = (struct bsym_dat*)pCB->control.pASymNext; pCB->control.aSymMax = GET_NRA_UCHAR(&p->bsym_count); pCB->colorCode = GET_NRA_UCHAR(&p->bsym_color); pCB->symCode = GET_NRA_SHORT(&p->bsym_code); pCB->xOffset = 0; pCB->yOffset = 0; pCB->control.aSymNext = 1; pCB->control.pASymNext = (struct asym_dat*)(++p); } else { /* series already in progress, return the next additional symbol */ pCB->colorCode = GET_NRA_SHORT(&pCB->control.pASymNext->asym_data); pCB->symCode = GET_NRA_SHORT(&pCB->control.pASymNext->asym_code); pCB->xOffset = (unsigned int)(pCB->colorCode & 0xfc00) >> 10; pCB->yOffset = (unsigned int)(pCB->colorCode & 0x03f0) >> 4; if (pCB->xOffset > 0x20) pCB->xOffset = 0xffc0 | pCB->xOffset; if (pCB->yOffset > 0x20) pCB->yOffset = 0xffc0 | pCB->yOffset; pCB->colorCode = pCB->colorCode & 0x0f; pCB->control.aSymNext++; pCB->control.pASymNext++; } /* Now pick up the bitmap from the sym table */ if (LoadSymbolEntry(&pCB->symBits, m_drawparm.pslut, pCB->symCode)) { if (pCB->control.aSymNext < pCB->control.aSymMax) pCB->cmdStatus = GETSYM_MORE_SYM; /* good status and more sym */ else pCB->cmdStatus = GETSYM_OK; /* good status and no more sym */ return 1; } return 0; /* Sym code in expanded symbol not found in sym table */ } /*/////////////////////////////////////////////////////////////////////////// */ BOOL getFirstSym(GetSymControlBlock* pCB) { /* Look in the symbol table first. If not found, try esym table */ if (LoadSymbolEntry(&pCB->symBits, m_drawparm.pslut, pCB->symCode)) { pCB->cmdStatus = GETSYM_OK; return 1; } if (pCB->control.pASymNext = SearchESymbolEntry(m_drawparm.peslut, pCB->symCode)) { /* set up to retrieve base sym and each additional sym later */ pCB->control.aSymMax = 0; /* flag base symbol to be returned next */ return (getNextSym(pCB)); } pCB->cmdStatus = GETSYM_ERROR; /* symbol not found */ return 0; } struct pset_dat* findPset(unsigned char* ppsets, unsigned short numPsets, unsigned short level, unsigned short vs) { struct pset_dat* ppset = (struct pset_dat*)ppsets; unsigned char discriminator; int i; vs = vs - 'a' + 10; discriminator = ((unsigned char)level) << 4; discriminator |= (unsigned char) vs; for (i=0; i<(int)numPsets; i++) { if (ppset->pset_disc == discriminator) return ppset; ppset++; } return (struct pset_dat*)NULL; } int getColorPaletteNum(unsigned short level, unsigned short vs) { struct pset_dat* ppset; ppset = findPset(m_drawparm.ppset, m_drawparm.num_pset, level, vs); if (ppset) return (int)ppset->pset_cpalt; else return -1; /* Not Found */ } /*/////////////////////////////////////////////////////////////// // // Public Functions: // */ int getColorPalette(ColorPalette* pPal, unsigned short level, unsigned short vs) { int palNumber; /* palNumber depends on level, vs */ if ((palNumber = getColorPaletteNum(level, vs)) != -1) { LoadColEntry(pPal, m_drawparm.pclut, palNumber); return 1; } else return 0; } /*/////////////////////////////////////////////////////////////////////////// */ LineStyle getLineStyle(unsigned short level, unsigned short vs, unsigned short num_lstyle) { unsigned short palNumber = 0; if (num_lstyle < NRA_RESERVED_LINE_STYLES) return 0; /* palNumber depends on level, vs */ return LoadLineEntry(m_drawparm.pllut, palNumber, num_lstyle); } /*/////////////////////////////////////////////////////////////////////////// */ void getTextureStyle(TextureStyle* pTexture, unsigned short level, unsigned short vs, unsigned short style) { unsigned short palNumber = 0; /* palNumber depends on level, vs */ LoadTextureEntry(pTexture, m_drawparm.ptlut, palNumber, style); } /*/////////////////////////////////////////////////////////////////////////// */ /* Function returns FALSE on error condition; else it returns TRUE */ BOOL getSymFont(GetSymControlBlock* pCB) { switch(pCB->cmdStatus) { case GETSYM_GET_FIRST_SYM: return (getFirstSym(pCB)); case GETSYM_GET_NEXT_SYM: return (getNextSym(pCB)); default: pCB->cmdStatus = GETSYM_ERROR; return 0; } } /**************************************************************************/ /* */ /* U S E M E !!!! - I'm a handy envelope function to get symbols! */ /* */ /* This routine will read one regular symbol or one expanded symbol from */ /* the draw parameters file. 'code' is the symbol code to read. 'data' */ /* is an arry of 'max' size provided by caller. Each element in 'data' */ /* corresponds to a bit image (card) for symbol. Of course, only expanded*/ /* symbols will have more than one bit image. The function returns the */ /* number of elements in 'data' that were filled in. Return code of 0 */ /* means some sort of error happended. */ /* Historical note: This routine was extracted from mapLab and donated */ /* to the public domain to better humanity. The infamous 'labH' parameter*/ /* was removed (used to log errors). The caller should watch the return */ /* code and make their error messages. */ /* Callers, please use 'MAX_SYMBOL_LAYERS' when sizing your 'data'! */ /* */ /**************************************************************************/ int getSymbol(int code, labSymbol *data, int max) { int count, i; GetSymControlBlock symCB; char s[200]; count = 0; symCB.symCode = (unsigned short)code; symCB.cmdStatus = GETSYM_GET_FIRST_SYM; if (getSymFont(&symCB)) { if (symCB.cmdStatus != GETSYM_ERROR) { data[0].color = (int)symCB.colorCode; data[0].offx = 0; data[0].offy = 0; for (i = 0 ; i < 16 ; i++) data[0].bits[i] = symCB.symBits.dotSym16[i]; count++; while (symCB.cmdStatus == GETSYM_MORE_SYM) { symCB.cmdStatus = GETSYM_GET_NEXT_SYM; if (getSymFont(&symCB)) { if (count < max) { data[count].color = (int)symCB.colorCode; data[count].offx = symCB.xOffset; data[count].offy = symCB.yOffset; for (i = 0 ; i < 16 ; i++) data[count].bits[i] = symCB.symBits.dotSym16[i]; count++; } } else { /* labLogMsg(labH, "getSymFont() returned failure: get next symbol"); */ /* symCB.cmdStatus = GETSYM_ERROR; */ return(0); } } } else return(0); /* labLogMsg(labH, "getSymFont() returned with status GETSYM_ERROR"); */ } else { /* sprintf(s, "getSymFont() returned failure: status = %d", symCB.cmdStatus); labLogMsg(labH, s); */ return(0); } /* if (count == 0) { sprintf(s, "Symbol Code for above error is %04x", code); labLogMsg(labH, s); } */ return(count); } /**************************************************************************/ /* Calculate bounding box for visible portion of symbol. */ /* 'code' is a symbol or expanded symbol drawparm code. */ /* 'width' and 'height' are filled in. Return 0 for success. */ /* 'offx' and 'offy' give the offset for the center of this symbol's bbox */ /* relative to the lower left corner of the first card (i.e. the base */ /* point). Positive values mean center is above and/or to the right. */ /* Example: offx,offy == 0,0 means that symbol is centered over base pt. */ /* Since drawparm symbols are bitmaps, width and height are in terms of */ /* bits. These bits may or may not correspond to pixels when drawn on */ /* mapLab, NRA players, etc. Only the visible portion of the symbol is */ /* looked at. Blank cards and blank portions of cards are ignored. */ /* Fine print: Symbol doesn't have to be centered around base point for */ /* this routine to work. Assuming standard magnification (16 by 16) */ /* only. This routine not recommended for fonts, only pictures. */ /**************************************************************************/ int getSymbol_bbox(int code, int *width, int *height, int *offx, int *offy) { int sx, sy, llx, lly, urx, ury; labSymbol data[MAX_SYMBOL_LAYERS]; int rc, i; /* Get the "card" or "cards" for this symbol */ rc = getSymbol(code, data, MAX_SYMBOL_LAYERS); if (!rc) return(1); /* Let's draw our symbol on a classic Cartesian grid. sx, sy is */ /* our cursor which moves for each card and is the lower left */ /* corner. We'll start with the origin. */ sx = 0; sy = 0; /* Initialize icon's bbox */ llx = lly = 30000; urx = ury = -30000; /* Scan each "card" for visible bits */ for (i = 0 ; i < rc ; i++) { sx = sx + data[i].offx; sy = sy + data[i].offy; /* Look at this card. If there are visible bits, */ /* then update the icon's bbox. */ { int tx, ty; unsigned short row; int ii, ij; /* scan card row by row, starting at upper left corner */ tx = sx; ty = sy + 15; for (ii = 0 ; ii < 16 ; ii++) { row = data[i].bits[ii]; for (ij = 0 ; ij < 16 ; ij++) { if (row & 0x8000) { if (tx < llx) llx = tx; if (tx > urx) urx = tx; if (ty < lly) lly = ty; if (ty > ury) ury = ty; } tx++; row = row << 1; } tx = sx; ty--; } } } if (urx > -30000) { *width = urx - llx; *height = ury - lly; *offx = (urx + llx) / 2; *offy = (ury + lly) / 2; } else *width = *height = *offx = *offy = 0; return(0); } /**************************************************************************/ /* Custom line getter for the dxf reader routine. */ /**************************************************************************/ static char *fgets_custom(char *s, int n, FILE *fp) { int i; char c; i = 0; n--; while ((i < n) && ((c = getc(fp)) != EOF)) { if ((c < (char)0x0a) || ((unsigned char)c > 0x7f)) continue; if ((c == '\r') || (c == '\n')) n = -1; else s[i++] = c; } s[i] = 0; if ((c == EOF) && (i == 0)) return(NULL); else return(s); } /**************************************************************************/ /* dxf reader routine for the getVectorIcon routine. */ /* Grabs lines and polylines, placing them into 'data', no more than 'max'*/ /* 'name' is the filename and 'layer' is name of the layer to get. Other */ /* layers are ignored. */ /**************************************************************************/ static int readDXF(char *fn, char *layer, IconVector *data, int max) { #define SKIP 1 #define LINE 2 #define POLYLINE 3 #define DONE 4 FILE *fp; char sc[100], sd[100]; int i, state, count, code; /* 'count' overruns 'max' sometimes. Do this until proper fix. */ max = max - 4; fp = fopen(fn, "r"); if (!fp) return(0); state = SKIP; count = 0; while (state != DONE) { if (!fgets_custom(sc, 100, fp)) return(0); if (!fgets_custom(sd, 100, fp)) return(0); code = atoi(sc); if ((state == SKIP) && (code != 0)) continue; switch (code) { case 0: if (!strcmp(sd, "EOF")) { state = DONE; } else if (!strcmp(sd, "LINE")) { state = LINE; } else if (!strcmp(sd, "POLYLINE")) { state = POLYLINE; } else if (!strcmp(sd, "VERTEX")) { if ((state != SKIP) && (count >= max)) { data[count-1].end = (char)1; state = DONE; } } else if (!strcmp(sd, "SEQEND")) { if (state != SKIP) { data[count-1].end = (char)1; state = SKIP; } } break; case 8: if (strcmp(sd, layer)) state = SKIP; break; case 10: data[count].x = atof(sd); break; case 20: data[count].y = atof(sd); data[count++].end = (char)0; break; case 11: if (state != LINE) break; data[count].x = atof(sd); break; case 21: if (state != LINE) break; data[count].y = atof(sd); data[count++].end = (char)1; state = SKIP; break; } } fclose(fp); return(count); } /*************************************************************/ /* Vector Icon Cache Code Follows */ /* Least Recently Used (LRU) method */ /*************************************************************/ #define VICON_CACHE_SIZE 7 /* Number of icons that can be cached */ typedef struct { char fn[MAX_FILENAME]; /* filename of cached icon */ char layer[MAX_ASSOC_STR]; /* layer name of cached icon */ long age; /* -1: not used >=0: age, 0 is youngest */ IconVector *data; /* data of cached icon */ int size; /* point count of data */ } ViconCacheType; static int ViconCacheInitialized = 0; /* Boolean to insure proper initialization */ static ViconCacheType ViconCache[VICON_CACHE_SIZE]; /* The icon cache */ static void InitViconCache(void) { int i; if (ViconCacheInitialized) return; for (i = 0 ; i < VICON_CACHE_SIZE ; i++) ViconCache[i].age = -1; ViconCacheInitialized = 1; } static void FreeViconCache(void) { int i; if (!ViconCacheInitialized) return; for (i = 0 ; i < VICON_CACHE_SIZE ; i++) if (ViconCache[i].age >= 0) free(ViconCache[i].data); ViconCacheInitialized = 0; } static int readViconCache(char *fn, char *layer, IconVector *data, int max) { int i, j, n; for (i = 0 ; i < VICON_CACHE_SIZE ; i++) if ((ViconCache[i].age >= 0) && (ViconCache[i].age < 30000)) ViconCache[i].age++; for (i = 0 ; i < VICON_CACHE_SIZE ; i++) if (ViconCache[i].age >= 0) if (!strcmp(fn, ViconCache[i].fn) && !strcmp(layer, ViconCache[i].layer)) break; if (i == VICON_CACHE_SIZE) return(0); ViconCache[i].age = 0; n = ViconCache[i].size; if (n > max) n = max; for (j = 0 ; j < n ; j++) data[j] = ViconCache[i].data[j]; return(n); } static void writeViconCache(char *fn, char *layer, IconVector *data, int count) { int i, j, old; for (i = 0 ; i < VICON_CACHE_SIZE ; i++) if (ViconCache[i].age < 0) break; if (i < VICON_CACHE_SIZE) { ViconCache[i].data = (IconVector *)malloc(sizeof(IconVector) * MAX_VECTOR_ICON_PTS); if (!ViconCache[i].data) return; } else { old = -1; for (j = 0 ; j < VICON_CACHE_SIZE ; j++) if (ViconCache[j].age > old) { i = j; old = ViconCache[j].age; } } strncpy(ViconCache[i].fn, fn, MAX_FILENAME); strncpy(ViconCache[i].layer, layer, MAX_ASSOC_STR); ViconCache[i].age = 0; if (count > MAX_VECTOR_ICON_PTS) count = MAX_VECTOR_ICON_PTS; for (j = 0 ; j < count ; j++) ViconCache[i].data[j] = data[j]; ViconCache[i].size = count; } /*************************************************************/ /* End of Cache Code */ /*************************************************************/ /**************************************************************************/ /* Get a vector icon from file. 'name' is the filename of the dxf file. */ /* 'layer' is the name of the layer to retrieve data for. Data for other */ /* layers will be ignored. There is supposed to be one vector icon per */ /* layer, enabling multiple icons to exist in one dxf file. On input, */ /* the first two elements in 'data' (lower left and upper right) specify */ /* the destination bbox to fit (scale and translate) the vector icon */ /* points into. On output, the points are placed in 'data'. 'max' is */ /* the maximum number of points to place in 'data'. The number of points */ /* retrieved is returned or zero if there is an error. Callers please */ /* use MAX_VECTOR_ICON_PTS to dimension your arrays with. */ /**************************************************************************/ int getVectorIcon(char *name, char *layer, IconVector *data, int max) { IconVector llDest, urDest; IconVector llSrc, urSrc; int count, i; IconVector ratio; /* Save destination bbox where source pts will be translated and scaled into */ llDest = data[0]; urDest = data[1]; if (1) /* Use Vector Icon Cache */ { InitViconCache(); /* (in case drawparm module wasn't initialized) */ count = readViconCache(name, layer, data, max); if (!count) { count = readDXF(name, layer, data, max); if (!count) return(0); writeViconCache(name, layer, data, count); } } else { count = readDXF(name, layer, data, max); if (!count) return(0); } /* Determine bbox for source points */ llSrc.x = llSrc.y = 10e20; urSrc.x = urSrc.y = 10e-20; for (i = 0 ; i < count ; i++) { if (data[i].x < llSrc.x) llSrc.x = data[i].x; if (data[i].x > urSrc.x) urSrc.x = data[i].x; if (data[i].y < llSrc.y) llSrc.y = data[i].y; if (data[i].y > urSrc.y) urSrc.y = data[i].y; } /* Get scaling factor, but don't divide by zero. */ if ((urSrc.x - llSrc.x == 0.0) || (urSrc.y - llSrc.y == 0.0)) { ratio.x = 0.0; ratio.y = 0.0; } else { ratio.x = (urDest.x - llDest.x) / (urSrc.x - llSrc.x); ratio.y = (urDest.y - llDest.y) / (urSrc.y - llSrc.y); } /* Scale, translate each point from source bbox to dest bbox */ for (i = 0 ; i < count ; i++) { data[i].x = (data[i].x - llSrc.x) * ratio.x + llDest.x; data[i].y = (data[i].y - llSrc.y) * ratio.y + llDest.y; } return(count); } /*/////////////////////////////////////////////////////////////////////////// */ void DumpSymBitMap(GetSymControlBlock* pCB) { int i; printf("Color = %x, Xoff = %x, yOff = %x\n",pCB->colorCode,pCB->xOffset,pCB->yOffset); for (i=0; i<16; i++) { printf("%04x\n", pCB->symBits.dotSym16[i]); } } #if 0 int main() { unsigned short styleNum; unsigned short style; ColorPalette Pal; TextureStyle tStyle; int i; GetSymControlBlock symCB; if (DprmDoc("fl_ga") == 0) { printf("Something's wrong with the drawparm file paris.dpm\n"); return 1; } /* check out line styles */ for (styleNum=0; styleNum<16; styleNum++) { style = getLineStyle(0, 'c', styleNum); printf("\nStyle = %04X\n", style); } /* check out color palettes */ getColorPalette(&Pal, 0, 'c'); printf("\nRED GREEN BLUE\n"); for (i=0; i<16;i++) { printf("%02x %02x %02x\n", Pal.rgb888[i].red, Pal.rgb888[i].green, Pal.rgb888[i].blue); } /* check out texture styles */ for (styleNum=0; styleNum<16; styleNum++) { printf("\n Style # %d\n", styleNum); getTextureStyle(&tStyle, 0, 'c', styleNum); for (i=0; i<8;i++) { printf("%02x ", tStyle.dotMap8[i]); } } /* check out symbols */ /* Hardcoding for testing. I know the first sym is this! */ for (symCB.symCode = 0xf048; symCB.symCode<0xf04b; symCB.symCode++) { printf("\n Symbol %04x\n", symCB.symCode); symCB.cmdStatus = GETSYM_GET_FIRST_SYM; if (getSymFont(&symCB)) { printf("*** SUCCESS ... status = %d***\n", symCB.cmdStatus); if (symCB.cmdStatus == GETSYM_OK) { for (i=0; i<16;i++) { printf("%04x\n", symCB.symBits.dotSym16[i]); } } } else printf("*** FAIL ... status = %d***\n", symCB.cmdStatus); } /* check out Expanded symbols */ /* Hardcoding for testing. I know the first sym is this! */ for (symCB.symCode = 0xf249; symCB.symCode<0xf24c; symCB.symCode++) { printf("\n Symbol %04x\n", symCB.symCode); symCB.cmdStatus = GETSYM_GET_FIRST_SYM; if (getSymFont(&symCB)) { printf("*** SUCCESS ... status = %d***\n", symCB.cmdStatus); if (symCB.cmdStatus == GETSYM_ERROR) continue; /* probably sym not found, do next eSym */ /* display the bitmap of base sym */ DumpSymBitMap(&symCB); /* if status == GETSYM_OK, meaning 1 sym only, continue with next eSym */ /* Otherwise, loop until status != GETSYM_MORE_SYM */ while (symCB.cmdStatus == GETSYM_MORE_SYM) { symCB.cmdStatus = GETSYM_GET_NEXT_SYM; if (getSymFont(&symCB)) { DumpSymBitMap(&symCB); } else { printf("*** ERROR getting Additional Sym ***\n"); break; } } } else printf("*** FAIL ... status = %d***\n", symCB.cmdStatus); } return 0; } #endif #include "tcl.h" #include "tk.h" static Tk_Window mainWindow; main (int argc, char **argv) { char string[1000]; Tcl_Interp *interp; int code, foo_width, foo_height, foo_index; labSymbol data[MAX_SYMBOL_LAYERS]; static char foo_bits[1000]; int i,j, rc; unsigned short styleNum; unsigned short style; ColorPalette Pal; TextureStyle tStyle; GetSymControlBlock symCB; unsigned short row, mask, maskleft, one; if (argc < 2) { printf("must give icon number on command line\n"); exit(1); } sscanf(argv[1],"%x",&code); if (DprmDoc("fl-ga") == 0) { printf("Something's wrong with the drawparm file fl-ga.dpm\n"); return 1; } /* Get the "card" or "cards" for this symbol */ rc = getSymbol(code, data, MAX_SYMBOL_LAYERS); if (!rc) { printf("getSymbol failed\n"); return(1); } /* load into a static bitmap */ memset(foo_bits,0,1000); foo_index = 0; for (i=0; i<16; i++) { /* swap bits */ row = 0; one = 1; maskleft = 1; for (j=0;j<16;j++) { /* get bit j */ mask = one << 15-j; if (data->bits[i] & mask) row |= maskleft; maskleft = maskleft << 1; } foo_bits[foo_index++] = row; row = row >> 8; foo_bits[foo_index++] = row; printf("--%x\n",row); } /* define */ foo_height = 16; foo_width = 16; interp = Tcl_CreateInterp(); mainWindow = Tk_CreateMainWindow(interp, 0, "dpex", "Tk"); if (mainWindow == NULL) { printf("Failed window creation.\n"); fprintf(stderr, "%s\n", interp->result); exit(1); } Tk_GeometryRequest(mainWindow, 200, 200); Tk_DefineBitmap(interp,Tk_GetUid("foo"), foo_bits, foo_width, foo_height); strcpy(string,"canvas .c -background white"); rc = Tcl_Eval(interp, string); if (rc == TCL_ERROR) printf("Exiting unsuccessfully\n"); if (rc == TCL_OK) printf("Exiting successfully\n"); strcpy(string,"pack .c"); rc = Tcl_Eval(interp, string); if (rc == TCL_ERROR) printf("Exiting unsuccessfully\n"); if (rc == TCL_OK) printf("Exiting successfully\n"); strcpy(string,".c create bitmap 30 30 -bitmap foo"); rc = Tcl_Eval(interp, string); if (rc == TCL_ERROR) printf("Exiting unsuccessfully\n"); if (rc == TCL_OK) printf("Exiting successfully\n"); Tk_MainLoop(); } #if 0 /* Draw a symbol or one card of an expanded symbol. The input coordinate */ /* is the lower left corner. */ /**************************************************************************/ static void labDrawSymbolBits(labSymbol *data, int mag, int x, int y, Display *dpy, Window xwin, GC gc) { int tx, ty, numpts; XPoint pts[512]; unsigned short row; int i, j, use; tx = x; ty = y - (labCharDim(mag, FALSE, FALSE) - 1); numpts = 0; for (i = 0 ; i < 16 ; i++) if ((mag != 0) || !(i % 2)) { row = data->bits[i]; for (j = 0 ; j < 16 ; j++) { use = (mag > 1) || !(j % 2); if (use && (row & 0x8000)) { pts[numpts].x = tx; pts[numpts++].y = ty; if (mag == 3) { pts[numpts].x = tx+1; pts[numpts++].y = ty; } } if (use) tx++; if (mag == 3) tx++; row = row << 1; } tx = x; ty++; } XDrawPoints(dpy, xwin, gc, pts, numpts, CoordModeOrigin); } #endif