static int connect_socket(int quiet) { int s; char *env; struct hostent *hp; struct sockaddr_in sin; int opt; #if defined(_WIN32) WORD wVersionRequested = MAKEWORD(1, 1); WSADATA wsaData; if (WSAStartup(wVersionRequested, &wsaData) != 0) { fprintf(stderr, "Can't find a usable WinSock DLL\n"); return -1; } #endif s = socket(PF_INET, /* get a socket descriptor */ SOCK_STREAM, /* stream socket */ IPPROTO_TCP); /* use TCP protocol */ if (s == -1) { if (!quiet) perror("socket"); return -1; } opt = 1; #ifdef SO_REUSEADDR setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)); #endif env = (char *)gks_getenv("GKS_CONID"); if (env) if (!*env) env = NULL; if (!env) env = (char *)gks_getenv("GKSconid"); if ((hp = gethostbyname(env != NULL ? env : "127.0.0.1")) == 0) { if (!quiet) perror("gethostbyname"); return -1; } memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr_list[0]))->s_addr; sin.sin_port = htons(PORT); if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) == -1) { if (!quiet) perror("connect"); return -1; } return s; }
int gks_open_font(void) { const char *path; char fontdb[MAXPATHLEN]; int fd; path = gks_getenv("GKS_FONTPATH"); if (path == NULL) { path = gks_getenv("GRDIR"); if (path == NULL) path = GRDIR; } strcpy(fontdb, (char *)path); #ifndef _WIN32 strcat(fontdb, "/fonts/gksfont.dat"); #else strcat(fontdb, "\\FONTS\\GKSFONT.DAT"); #endif fd = gks_open_file(fontdb, "r"); return fd; }
void gks_drv_plugin(int fctid, int dx, int dy, int dimx, int *ia, int lr1, double *r1, int lr2, double *r2, int lc, char *chars, void **ptr) { static const char *name = NULL; static void (*entry)(ENTRY_ARGS) = NULL; const char *env; if (name == NULL) { name = NAME; if ((env = gks_getenv("GKS_PLUGIN")) != NULL) name = env; *(void **)(&entry) = load_library(name); } if (entry != NULL) (*entry)(fctid, dx, dy, dimx, ia, lr1, r1, lr2, r2, lc, chars, ptr); }
static void *load_library(const char *name) { char pathname[MAXPATHLEN], symbol[255]; #ifdef _WIN32 HINSTANCE handle; #else void *handle; const char *grdir, *error; #endif void *entry = NULL; sprintf(pathname, "%s.%s", name, EXTENSION); #ifdef _WIN32 handle = LoadLibrary(pathname); #else handle = dlopen(pathname, RTLD_LAZY); if (handle == NULL) { sprintf(pathname, "%s/%s.%s", "./", name, EXTENSION); handle = dlopen(pathname, RTLD_LAZY); } if (handle == NULL) { grdir = gks_getenv("GRDIR"); if (grdir == NULL) grdir = GRDIR; sprintf(pathname, "%s/lib/%s.%s", grdir, name, EXTENSION); handle = dlopen(pathname, RTLD_LAZY); } #endif if (handle != NULL) { sprintf(symbol, "gks_%s", name); #ifdef _WIN32 entry = GetProcAddress(handle, symbol); #else entry = dlsym(handle, symbol); #endif if (entry == NULL) { #ifdef _WIN32 gks_perror("%s: unresolved symbol", symbol); #else if ((error = dlerror()) != NULL) gks_perror((char *) error); #endif } } else { #ifdef _WIN32 gks_perror("%s: can't load library", pathname); #else if ((error = dlerror()) != NULL) gks_perror((char *) error); #endif } return entry; }
static void *load_library(const char *name) { char pathname[MAXPATHLEN], symbol[255]; #ifdef _WIN32 HINSTANCE handle; LPCTSTR grdir; char grbin[MAXPATHLEN]; #else void *handle; const char *grdir, *error; #endif void *entry = NULL; sprintf(pathname, "%s.%s", name, EXTENSION); #ifdef _WIN32 handle = LoadLibrary(pathname); if (handle == NULL) { grdir = gks_getenv("GRDIR"); if (grdir == NULL) grdir = GRDIR; sprintf(grbin, "%s/bin", grdir); SetDllDirectory(grbin); handle = LoadLibrary(pathname); } #else handle = dlopen(pathname, RTLD_LAZY); if (handle == NULL) { sprintf(pathname, "%s/%s.%s", "./", name, EXTENSION); handle = dlopen(pathname, RTLD_LAZY); } if (handle == NULL) { grdir = gks_getenv("GRDIR"); if (grdir == NULL) grdir = GRDIR; sprintf(pathname, "%s/lib/%s.%s", grdir, name, EXTENSION); handle = dlopen(pathname, RTLD_LAZY); } #endif if (handle != NULL) { sprintf(symbol, "gks_%s", name); #ifdef _WIN32 entry = (void *)GetProcAddress(handle, symbol); #else entry = dlsym(handle, symbol); #endif if (entry == NULL) { #ifdef _WIN32 gks_perror("%s: unresolved symbol", symbol); #else if ((error = dlerror()) != NULL) gks_perror((char *)error); #endif } } else { #ifdef _WIN32 DWORD ec = 0; ec = GetLastError(); gks_perror("%s: can't load library, error %d (0x%x)", pathname, ec, ec); #else if ((error = dlerror()) != NULL) gks_perror((char *)error); #endif } return entry; }
void gks_drv_socket(int fctid, int dx, int dy, int dimx, int *ia, int lr1, double *r1, int lr2, double *r2, int lc, char *chars, void **ptr) { ws_state_list *wss; const char *command = NULL, *env; int retry_count; char *cmd = NULL; wss = (ws_state_list *)*ptr; switch (fctid) { case 2: gkss = (gks_state_list_t *)*ptr; wss = (ws_state_list *)gks_malloc(sizeof(ws_state_list)); if (ia[2] == 411) { command = gks_getenv("GKS_QT"); if (command == NULL) { env = gks_getenv("GRDIR"); if (env == NULL) env = GRDIR; cmd = (char *)gks_malloc(MAXPATHLEN); #ifndef _WIN32 #ifdef __APPLE__ sprintf(cmd, "%s/Applications/gksqt.app/Contents/MacOS/gksqt", env); #else sprintf(cmd, "%s/bin/gksqt", env); #endif #else sprintf(cmd, "%s\\bin\\gksqt.exe", env); #endif command = cmd; } } for (retry_count = 1; retry_count <= 10; retry_count++) { if ((wss->s = connect_socket(retry_count != 10)) == -1) { if (command != NULL && retry_count == 1) { if (start(command) != 0) gks_perror("could not auto-start GKS Qt application"); } #ifndef _WIN32 usleep(300000); #else Sleep(300); #endif } else break; } if (cmd != NULL) free(cmd); if (wss->s == -1) { gks_perror("can't connect to GKS socket application\n" "Did you start 'gksqt'?\n"); gks_free(wss); wss = NULL; ia[0] = ia[1] = 0; } else *ptr = wss; break; case 3: close_socket(wss->s); if (wss->dl.buffer) { free(wss->dl.buffer); } gks_free(wss); wss = NULL; break; case 8: if (ia[1] & GKS_K_PERFORM_FLAG) { send_socket(wss->s, (char *)&wss->dl.nbytes, sizeof(int)); send_socket(wss->s, wss->dl.buffer, wss->dl.nbytes); } break; } if (wss != NULL) { gks_dl_write_item(&wss->dl, fctid, dx, dy, dimx, ia, lr1, r1, lr2, r2, lc, chars, gkss); } }
unsigned char *gks_ft_get_bitmap(int *x, int *y, int *width, int *height, gks_state_list_t *gkss, const char *text, int length) { FT_Face face; /* font face */ FT_Vector pen; /* glyph position */ FT_BBox bb; /* bounding box */ FT_Vector bearing; /* individual glyph translation */ FT_UInt previous; /* previous glyph index */ FT_Vector spacing; /* amount of additional space between glyphs */ FT_ULong textheight; /* textheight in FreeType convention */ FT_Error error; /* error code */ FT_Matrix rotation; /* text rotation matrix */ FT_UInt size; /* number of pixels of the bitmap */ FT_String *file; /* concatenated font path */ const FT_String *font, *prefix; /* font file name and directory */ FT_UInt *unicode_string; /* unicode text string */ FT_Int halign, valign; /* alignment */ FT_Byte *mono_bitmap = NULL; /* target for rendered text */ FT_Int num_glyphs; /* number of glyphs */ FT_Vector align; FT_Bitmap ftbitmap; FT_UInt codepoint; int i, textfont, dx, dy, value, pos_x, pos_y; unsigned int j, k; double angle; const int windowwidth = *width; const int direction = (gkss->txp <= 3 && gkss->txp >= 0 ? gkss->txp : 0); const FT_Bool vertical = (direction == GKS_K_TEXT_PATH_DOWN || direction == GKS_K_TEXT_PATH_UP); const FT_String *suffix_type1 = ".afm"; if (!init) gks_ft_init(); if (gkss->txal[0] != GKS_K_TEXT_HALIGN_NORMAL) { halign = gkss->txal[0]; } else if (vertical) { halign = GKS_K_TEXT_HALIGN_CENTER; } else if (direction == GKS_K_TEXT_PATH_LEFT) { halign = GKS_K_TEXT_HALIGN_RIGHT; } else { halign = GKS_K_TEXT_HALIGN_LEFT; } valign = gkss->txal[1]; if (valign != GKS_K_TEXT_VALIGN_NORMAL) { valign = gkss->txal[1]; } else { valign = GKS_K_TEXT_VALIGN_BASE; } textfont = abs(gkss->txfont); if (textfont >= 101 && textfont <= 131) textfont -= 100; else if (textfont > 1 && textfont <= 32) textfont = map[textfont - 1]; else textfont = 9; textfont = textfont - 1; font = gks_font_list[textfont]; if (font_face_cache[textfont] == NULL) { prefix = gks_getenv("GKS_FONTPATH"); if (prefix == NULL) { prefix = gks_getenv("GRDIR"); if (prefix == NULL) prefix = GRDIR; } file = (FT_String *) malloc(strlen(prefix) + 7 + strlen(font) + 4 + 1); strcpy(file, prefix); #ifndef _WIN32 strcat(file, "/fonts/"); #else strcat(file, "\\FONTS\\"); #endif strcat(file, font); strcat(file, ".pfb"); error = FT_New_Face(library, file, 0, &face); if (error == FT_Err_Unknown_File_Format) { gks_perror("unknown file format: %s", file); return NULL; } else if (error) { gks_perror("could not open font file: %s", file); return NULL; } if (strcmp(FT_Get_X11_Font_Format(face), "Type 1") == 0) { strcpy(file, prefix); #ifndef _WIN32 strcat(file, "/fonts/"); #else strcat(file, "\\FONTS\\"); #endif strcat(file, font); strcat(file, suffix_type1); FT_Attach_File(face, file); } free(file); font_face_cache[textfont] = face; } else { face = font_face_cache[textfont]; } num_glyphs = length; unicode_string = (FT_UInt *) malloc(length * sizeof(FT_UInt) + 1); if (textfont + 1 == 13) { symbol_to_unicode((FT_Bytes)text, unicode_string, num_glyphs); } else { utf_to_unicode((FT_Bytes)text, unicode_string, &num_glyphs); } textheight = nint(gkss->chh * windowwidth * 64 / caps[textfont]); error = FT_Set_Char_Size(face, nint(textheight * gkss->chxp), textheight, 72, 72); if (error) gks_perror("cannot set text height"); if (gkss->chup[0] != 0.0 || gkss->chup[1] != 0.0) { angle = atan2f(gkss->chup[1], gkss->chup[0]) - M_PI / 2; rotation.xx = nint( cosf(angle) * 0x10000L); rotation.xy = nint(-sinf(angle) * 0x10000L); rotation.yx = nint( sinf(angle) * 0x10000L); rotation.yy = nint( cosf(angle) * 0x10000L); FT_Set_Transform(face, &rotation, NULL); } else { FT_Set_Transform(face, NULL, NULL); } spacing.x = spacing.y = 0; if (gkss->chsp != 0.0) { error = FT_Load_Glyph(face, FT_Get_Char_Index(face, ' '), vertical ? FT_LOAD_VERTICAL_LAYOUT : FT_LOAD_DEFAULT); if (!error) { spacing.x = nint(face->glyph->advance.x * gkss->chsp); spacing.y = nint(face->glyph->advance.y * gkss->chsp); } else { gks_perror("cannot apply character spacing"); } } bb.xMin = bb.yMin = LONG_MAX; bb.xMax = bb.yMax = LONG_MIN; pen.x = pen.y = 0; previous = 0; for (i = 0; i < num_glyphs; i++) { codepoint = unicode_string[direction == GKS_K_TEXT_PATH_LEFT ? (num_glyphs - 1 - i) : i]; error = set_glyph(face, codepoint, &previous, &pen, vertical, &rotation, &bearing, halign); if (error) continue; bb.xMin = ft_min(bb.xMin, pen.x + bearing.x); bb.xMax = ft_max(bb.xMax, pen.x + bearing.x + 64*face->glyph->bitmap.width); bb.yMin = ft_min(bb.yMin, pen.y + bearing.y - 64*face->glyph->bitmap.rows); bb.yMax = ft_max(bb.yMax, pen.y + bearing.y); if (direction == GKS_K_TEXT_PATH_DOWN) { pen.x -= face->glyph->advance.x + spacing.x; pen.y -= face->glyph->advance.y + spacing.y; } else { pen.x += face->glyph->advance.x + spacing.x; pen.y += face->glyph->advance.y + spacing.y; } } *width = (int)((bb.xMax - bb.xMin) / 64); *height = (int)((bb.yMax - bb.yMin) / 64); if (bb.xMax <= bb.xMin || bb.yMax <= bb.yMin) { gks_perror("invalid bitmap size"); free(unicode_string); return NULL; } size = *width * *height; mono_bitmap = (FT_Byte *) safe_realloc(mono_bitmap, size); memset(mono_bitmap, 0, size); pen.x = 0; pen.y = 0; previous = 0; for (i = 0; i < num_glyphs; i++) { bearing.x = bearing.y = 0; codepoint = unicode_string[direction == GKS_K_TEXT_PATH_LEFT ? (num_glyphs - 1 - i) : i]; error = set_glyph(face, codepoint, &previous, &pen, vertical, &rotation, &bearing, halign); if (error) continue; pos_x = ( pen.x + bearing.x - bb.xMin) / 64; pos_y = (-pen.y - bearing.y + bb.yMax) / 64; ftbitmap = face->glyph->bitmap; for (j = 0; j < (unsigned int) ftbitmap.rows; j++) { for (k = 0; k < (unsigned int) ftbitmap.width; k++) { dx = k + pos_x; dy = j + pos_y; value = mono_bitmap[dy * *width + dx]; value += ftbitmap.buffer[j * ftbitmap.pitch + k]; if (value > 255) { value = 255; } mono_bitmap[dy * *width + dx] = value; } } if (direction == GKS_K_TEXT_PATH_DOWN) { pen.x -= face->glyph->advance.x + spacing.x; pen.y -= face->glyph->advance.y + spacing.y; } else { pen.x += face->glyph->advance.x + spacing.x; pen.y += face->glyph->advance.y + spacing.y; } } free(unicode_string); /* Alignment */ if (direction == GKS_K_TEXT_PATH_DOWN) { pen.x += spacing.x; pen.y += spacing.y; } else { pen.x -= spacing.x; pen.y -= spacing.y; } align.x = align.y = 0; if (valign != GKS_K_TEXT_VALIGN_BASE) { align.y = nint(gkss->chh * windowwidth * 64); FT_Vector_Transform(&align, &rotation); if (valign == GKS_K_TEXT_VALIGN_HALF) { align.x = nint(0.5 * align.x); align.y = nint(0.5 * align.y); } else if (valign == GKS_K_TEXT_VALIGN_TOP) { align.x = nint(1.2 * align.x); align.y = nint(1.2 * align.y); } else if (valign == GKS_K_TEXT_VALIGN_BOTTOM) { align.x = nint(-0.2 * align.x); align.y = nint(-0.2 * align.y); } } if (!vertical && halign != GKS_K_TEXT_HALIGN_LEFT) { FT_Vector right; right.x = face->glyph->metrics.width + face->glyph->metrics.horiBearingX; right.y = 0; if (right.x != 0) { FT_Vector_Transform(&right, &rotation); } pen.x += right.x - face->glyph->advance.x; pen.y += right.y - face->glyph->advance.y; if (halign == GKS_K_TEXT_HALIGN_CENTER) { align.x += pen.x / 2; align.y += pen.y / 2; } else if (halign == GKS_K_TEXT_HALIGN_RIGHT) { align.x += pen.x; align.y += pen.y; } } *x += (bb.xMin - align.x) / 64; *y += (bb.yMin - align.y) / 64; return mono_bitmap; }