static PyObject* validate_dict_key( Member* keymember, PyObject* owner, PyObject* dict ) { PyObject* key; PyObject* value; Py_ssize_t pos = 0; PyDictPtr newptr( PyDict_New() ); if( !newptr ) return 0; while( PyDict_Next( dict, &pos, &key, &value ) ) { PyObjectPtr keyptr( member_validate( keymember, owner, _py_null, key ) ); if( !keyptr ) return 0; PyObjectPtr valptr( newref( value ) ); if( !newptr.set_item( keyptr, valptr ) ) return 0; } return newptr.release(); }
font * ttf_write_tga (char *name, int32_t pointsize) { uint32_t rmask, gmask, bmask, amask; double glyph_per_row; char filename[200]; SDL_Surface *dst; uint32_t height; uint32_t width; double maxx; double maxy[TTF_GLYPH_MAX]; uint32_t c; int x; int y; double h; font *f; snprintf(filename, sizeof(filename), "%s_pointsize%u.tga", name, pointsize); if (tex_find(filename)) { return (0); } /* * x glyphs horizontally and y vertically. */ glyph_per_row = 16; f = ttf_new(name, pointsize, TTF_STYLE_NORMAL); if (!f) { ERR("could not create font %s", name); } maxx = 0; memset(maxy, 0, sizeof(maxy)); /* * Find the largest font glyph pointsize. */ x = 0; y = 0; height = 0; for (c = TTF_GLYPH_MIN; c < TTF_GLYPH_MAX; c++) { if (f->tex[c].image) { maxx = max(maxx, f->tex[c].image->w); maxy[y] = max(maxy[y], f->tex[c].image->h); } if (++x >= glyph_per_row) { x = 0; height += maxy[y]; y++; } } if (!maxx) { ERR("no glyphs in font %s", name); } width = glyph_per_row * maxx; if (MULTIPLE_BITS(width)) { width = nextpoweroftwo(width); } height += 40; if (MULTIPLE_BITS(height)) { height = nextpoweroftwo(height); } /* * Make a large surface for all glyphs. */ #if SDL_BYTEORDER == SDL_BIG_ENDIAN rmask = 0xff000000; gmask = 0x00ff0000; bmask = 0x0000ff00; amask = 0x000000ff; #else rmask = 0x000000ff; gmask = 0x0000ff00; bmask = 0x00ff0000; amask = 0xff000000; #endif dst = SDL_CreateRGBSurface(0, width, height, 32, rmask, gmask, bmask, amask); if (!dst) { ERR("no surface created for size %dx%d font %s", width, height, name); } newptr(dst, "SDL_CreateRGBSurface"); /* * Blit each glyph to the large surface. */ x = 0; y = 0; h = 0; for (c = TTF_GLYPH_MIN; c < TTF_GLYPH_MAX; c++) { if (f->tex[c].image) { SDL_Rect dstrect = { maxx * x, h, maxx, maxy[y] }; SDL_BlitSurface(f->tex[c].image, 0, dst, &dstrect); } if (++x >= glyph_per_row) { x = 0; h += maxy[y]; y++; } } /* * Convert the black border smoothing that ttf adds into alpha. */ { double x; double y; for (x = 0; x < dst->w; x++) { for (y = 0; y < dst->h; y++) { color c; c = getPixel(dst, x, y); if ((c.a == 255) && (c.r == 255) && (c.g == 255) && (c.b == 255)) { /* * Do nothing. */ } else if ((c.a == 0) && (c.r == 0) && (c.g == 0) && (c.b == 0)) { /* * Do nothing. */ } else { /* * Convery gray to white with alpha. */ c.a = (c.r + c.g + c.b) / 3; c.r = 255; c.g = 255; c.b = 255; } putPixel(dst, x, y, c); } } } #define MAX_TEXTURE_HEIGHT 4096 if (dst->h > MAX_TEXTURE_HEIGHT) { ERR("ttf is too large"); } uint8_t filled_pixel_row[MAX_TEXTURE_HEIGHT] = {0}; /* * What the hell am I doing here? The ttf library returns incorrect * boounds for the top and bottom of glyphs, so I'm looking for a line of * no pixels above and below each glyph so I can really find the texture * bounds of a glyph. This allows squeezing of text together. */ { int x; int y; for (y = 0; y < dst->h; y++) { for (x = 0; x < dst->w; x++) { color c; c = getPixel(dst, x, y); if (c.r || c.g || c.b || c.a) { filled_pixel_row[y] = true; break; } } } } /* * Work our the tex co-ords for each glyph in the large tex. */ x = 0; y = 0; h = 0; int d1_max = 0; int d2_max = 0; for (c = TTF_GLYPH_MIN; c < TTF_GLYPH_MAX; c++) { { int y = (h + (h + f->glyphs[c].height)) / 2; int miny = y; int maxy = y; for (;;) { if (!filled_pixel_row[miny]) { break; } miny--; if (miny <= 0) { break; } } for (;;) { if (!filled_pixel_row[maxy]) { break; } maxy++; if (maxy >= MAX_TEXTURE_HEIGHT - 1) { break; } } int d1 = y - miny; if (d1 > d1_max) { d1_max = d1; } int d2 = maxy - y; if (d2 > d2_max) { d2_max = d2; } } if (++x >= glyph_per_row) { x = 0; h += maxy[y]; y++; } } x = 0; y = 0; h = 0; for (c = TTF_GLYPH_MIN; c < TTF_GLYPH_MAX; c++) { f->glyphs[c].texMinX = (double)(x * maxx) / (double)dst->w; f->glyphs[c].texMaxX = (double)((x * maxx) + f->glyphs[c].width) / (double)dst->w; { int y = (h + (h + f->glyphs[c].height)) / 2; int y1 = y - d1_max; int y2 = y + d2_max; if (y1 < 0) { y1 = 0; } f->glyphs[c].texMinY = (double)(y1) / (double)dst->h; f->glyphs[c].texMaxY = (double)(y2) / (double)dst->h; } if (++x >= glyph_per_row) { x = 0; h += maxy[y]; y++; } } SDL_LockSurface(dst); stbi_write_tga(filename, dst->w, dst->h, STBI_rgb_alpha, dst->pixels); SDL_UnlockSurface(dst); texp tex; tex = tex_from_surface(dst, filename, filename); if (!tex) { ERR("could not convert %s to tex", filename); } /* * Work our the tex co-ords for each glyph in the large tex. */ x = 0; y = 0; h = 0; for (c = TTF_GLYPH_MIN; c < TTF_GLYPH_MAX; c++) { f->tex[c].image = dst; f->tex[c].tex = tex_get_gl_binding(tex); } /* * Save the glyph data. */ snprintf(filename, sizeof(filename), "%s_pointsize%u.data", name, pointsize); FILE *out = fopen(filename, "w"); fwrite(f->glyphs, sizeof(f->glyphs), 1, out); fclose(out); printf("wrote %s\n",filename); return (f); }
static int _elf_update_pointers(Elf *elf, char *outbuf, size_t len) { Elf_Scn *scn; Scn_Data *sd; char *data, *rawdata; elf_assert(elf); elf_assert(elf->e_data); elf_assert(!elf->e_parent); elf_assert(!elf->e_unmap_data); elf_assert(elf->e_kind == ELF_K_ELF); elf_assert(len >= EI_NIDENT); /* resize memory images */ if (len <= elf->e_dsize) { /* don't shorten the memory image */ data = elf->e_data; } else if ((data = (char*)realloc(elf->e_data, len))) { elf->e_dsize = len; } else { seterr(ERROR_IO_2BIG); return -1; } if (elf->e_rawdata == elf->e_data) { /* update frozen raw image */ memcpy(data, outbuf, len); elf->e_data = elf->e_rawdata = data; /* cooked data is stored outside the raw image */ return 0; } if (elf->e_rawdata) { /* update raw image */ if (!(rawdata = (char*)realloc(elf->e_rawdata, len))) { seterr(ERROR_IO_2BIG); return -1; } memcpy(rawdata, outbuf, len); elf->e_rawdata = rawdata; } if (data == elf->e_data) { /* nothing more to do */ return 0; } /* adjust internal pointers */ if (elf->e_ehdr && !elf->e_free_ehdr) { elf_assert(ptrinside(elf->e_ehdr, elf->e_data, elf->e_dsize)); newptr(elf->e_ehdr, elf->e_data, data); } if (elf->e_phdr && !elf->e_free_phdr) { elf_assert(ptrinside(elf->e_phdr, elf->e_data, elf->e_dsize)); newptr(elf->e_phdr, elf->e_data, data); } for (scn = elf->e_scn_1; scn; scn = scn->s_link) { elf_assert(scn->s_magic == SCN_MAGIC); elf_assert(scn->s_elf == elf); if ((sd = scn->s_data_1)) { elf_assert(sd->sd_magic == DATA_MAGIC); elf_assert(sd->sd_scn == scn); if (sd->sd_memdata && !sd->sd_free_data) { elf_assert(ptrinside(sd->sd_memdata, elf->e_data, elf->e_dsize)); if (sd->sd_data.d_buf == sd->sd_memdata) { newptr(sd->sd_memdata, elf->e_data, data); sd->sd_data.d_buf = sd->sd_memdata; } else { newptr(sd->sd_memdata, elf->e_data, data); } } } if ((sd = scn->s_rawdata)) { elf_assert(sd->sd_magic == DATA_MAGIC); elf_assert(sd->sd_scn == scn); if (sd->sd_memdata && sd->sd_free_data) { size_t off, len; if (elf->e_class == ELFCLASS32) { off = scn->s_shdr32.sh_offset; len = scn->s_shdr32.sh_size; } #if __LIBELF64 else if (elf->e_class == ELFCLASS64) { off = scn->s_shdr64.sh_offset; len = scn->s_shdr64.sh_size; } #endif /* __LIBELF64 */ else { seterr(ERROR_UNIMPLEMENTED); return -1; } if (!(rawdata = (char*)realloc(sd->sd_memdata, len))) { seterr(ERROR_IO_2BIG); return -1; } memcpy(rawdata, outbuf + off, len); if (sd->sd_data.d_buf == sd->sd_memdata) { sd->sd_data.d_buf = rawdata; } sd->sd_memdata = rawdata; } } } elf->e_data = data; return 0; }
static void ttf_set_color_key (SDL_Surface *glyph_surface, GLfloat *texcoord, uint8_t ckr, uint8_t ckg, uint8_t ckb, double *width, double *height) { SDL_Surface *tmp; uint32_t colorkey; /* * Use the surface width and height expanded to powers of 2 */ *width = glyph_surface->w; *height = glyph_surface->h; texcoord[0] = 0; // Min X texcoord[1] = 0; // Min Y texcoord[2] = (GLfloat)(((double)glyph_surface->w) / ((double)*width)); // Max X texcoord[3] = (GLfloat)(((double)glyph_surface->h) / ((double)*height)); // Max Y tmp = SDL_CreateRGBSurface(glyph_surface->flags, *width, *height, 32, #if SDL_BYTEORDER == SDL_BIG_ENDIAN 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF #else 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 #endif ); if (!tmp) { ERR("Failed to make RGB surface size %f %f: %s", *width, *height, SDL_GetError()); SDL_ClearError(); return; } newptr(tmp, "SDL_CreateRGBSurface"); /* * Set up so that colorkey pixels become transparent */ colorkey = SDL_MapRGBA(tmp->format, 0, 0, 0, 0); SDL_FillRect(tmp, 0, colorkey); colorkey = SDL_MapRGBA(glyph_surface->format, ckr, ckg, ckb, 0); #if (SDL_MAJOR_VERSION == 2) SDL_SetColorKey(glyph_surface, SDL_TRUE, colorkey); #else SDL_SetColorKey(glyph_surface, SDL_SRCCOLORKEY, colorkey); #endif SDL_FreeSurface(tmp); oldptr(tmp); }