Example #1
0
File: scan.c Project: dluco/ttf
int init_scanline(TTF_Scan_Line *scanline, int base_size) {
	CHECKPTR(scanline);

	RETINIT(SUCCESS);

	scanline->x = malloc(base_size * sizeof(*scanline->x));
	CHECKFAIL(scanline->x, warnerr("failed to alloc scanline"));

	scanline->size_x = base_size;
	scanline->num_intersections = 0;

	RETFAIL(free_scanline(scanline));
}
Example #2
0
File: scan.c Project: dluco/ttf
static int add_intersection(TTF_Scan_Line *scanline, float x) {
	CHECKPTR(scanline);

	RETINIT(SUCCESS);

	if (scanline->num_intersections+1 > scanline->size_x) {
		/* Increase size of scan-line storage for new intersection. */
		scanline->x = realloc(scanline->x, (scanline->size_x * 2) * sizeof(*scanline->x));
		CHECKFAIL(scanline->x, warnerr("failed to adjust scanline size"));

		scanline->size_x *= 2;
	}

	scanline->x[scanline->num_intersections++] = x;

	RET;
}
Example #3
0
void
vwarnx(const char *fmt, va_list ap)
{
    warnerr(0, fmt, ap);
}
Example #4
0
void ROKEN_LIB_FUNCTION
vwarnx(const char *fmt, va_list ap)
{
    warnerr(0, fmt, ap);
}
Example #5
0
void
verr(int eval, const char *fmt, va_list ap)
{
    warnerr(1, fmt, ap);
    exit(eval);
}
Example #6
0
File: bitmap.c Project: dluco/ttf
int save_bitmap(TTF_Bitmap *bitmap, const char *filename, const char *title) {
	FILE *fp = NULL;
	png_structp png_ptr = NULL;
	png_infop info_ptr = NULL;
	png_byte *row = NULL;

	RETINIT(SUCCESS);

	CHECKFAIL(bitmap, warn("failed to save uninitialized bitmap"));

	// Open file for writing (binary mode)
	fp = fopen(filename, "wb");
	CHECKFAIL(fp, warnerr("failed to open file '%s' for saving bitmap", filename));

	// Initialize the write structure
	png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
	CHECKFAIL(png_ptr, warn("failed to alloc png write struct"));

	// Initialize the info structure
	info_ptr = png_create_info_struct(png_ptr);
	CHECKFAIL(info_ptr, warn("failed to alloc png info struct"));

	// Setup libpng exception handling
	CHECKFAIL(setjmp(png_jmpbuf(png_ptr)) == 0, warn("error occurred during png creation"));

	png_init_io(png_ptr, fp);

	// Write header (8 bit colour depth)
	png_set_IHDR(png_ptr, info_ptr, bitmap->w, bitmap->h, 8,
			PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
			PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);

	// Set png title
	if (title) {
		png_text png_title;
		png_title.compression = PNG_TEXT_COMPRESSION_NONE;
		png_title.key = (png_charp) "Title";
		png_title.text = (png_charp) title;
		png_set_text(png_ptr, info_ptr, &png_title, 1);
	}

	png_write_info(png_ptr, info_ptr);

	// Allocate memory for one row (RBG = 3 bytes / pixel)
	row = (png_byte *) malloc((bitmap->w * 3) * sizeof(*row));
	CHECKFAIL(row, warnerr("failed to alloc png row"));

	// Write image data
	int x, y;
	for (y = 0; y < bitmap->h; y++) {
		for (x = 0; x < bitmap->w; x++) {
			set_rgb(&(row[x*3]), bitmap->data[y*bitmap->w + x]);
		}
		png_write_row(png_ptr, (png_bytep)row);
	}

	// End write
	png_write_end(png_ptr, NULL);

	RETRELEASE(
		/* RELEASE */
		if (row) free(row);
		if (info_ptr) png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
		if (png_ptr) png_destroy_write_struct(&png_ptr, &info_ptr);
		if (fp) fclose(fp);
	);
Example #7
0
File: scan.c Project: dluco/ttf
int scan_glyph(TTF_Font *font, TTF_Glyph *glyph) {
	CHECKPTR(font);
	CHECKPTR(glyph);

	RETINIT(SUCCESS);

	if (!glyph->outline) {
		warn("failed to scan uninitialized glyph outline");
		return FAILURE;
	} else if (glyph->outline->point < 0) {
		warn("failed to scan unscaled glyph outline");
		return FAILURE;
	} else if (glyph->number_of_contours == 0) {
		/* Zero-length glyph with no outline. */
		return SUCCESS;
	}

	TTF_Outline *outline = glyph->outline;
	TTF_Bitmap *bitmap = NULL;
	uint32_t bg, fg;

	if (font->raster_flags & RENDER_FPAA) {
		/* Anti-aliased rendering - oversample outline then downsample. */
		bg = 0xFFFFFF;
		fg = 0x000000;
		if (!glyph->bitmap) {
			glyph->bitmap = create_bitmap((outline->x_max - outline->x_min) / 2,
					(outline->y_max - outline->y_min) / 2, bg);
		}

		/* Intermediate oversampled bitmap. */
		bitmap = create_bitmap(outline->x_max - outline->x_min,
				outline->y_max - outline->y_min, bg);
	} else if (font->raster_flags & RENDER_ASPAA) {
		/* Sub-pixel rendering - oversample in x-direction then downsample. */
		bg = 0xFFFFFF;
		fg = 0x000000;
		if (!glyph->bitmap) {
			glyph->bitmap = create_bitmap((outline->x_max - outline->x_min) / 3,
					outline->y_max - outline->y_min, bg);
		}

		/* Intermediate oversampled bitmap. */
		bitmap = create_bitmap(outline->x_max - outline->x_min,
				outline->y_max - outline->y_min, bg);
	} else {
		/* Normal rendering - write directly to glyph bitmap. */
		bg = 0xFFFFFF;
		fg = 0x000000;
		if (!glyph->bitmap) {
			glyph->bitmap = create_bitmap(outline->x_max - outline->x_min,
					outline->y_max - outline->y_min, bg);
		}

		bitmap = glyph->bitmap;
	}

	/* Create a scan-line for each row in the scaled outline. */
	int num_scanlines = outline->y_max - outline->y_min;
	TTF_Scan_Line *scanlines = malloc(num_scanlines * sizeof(*scanlines));
	CHECKFAIL(scanlines, warnerr("failed to alloc glyph scan lines"));

	/* Find intersections of each scan-line with contour segments. */
	for (int i = 0; i < num_scanlines; i++) {
		TTF_Scan_Line *scanline = &scanlines[i];
		init_scanline(scanline, outline->num_contours * 2);
		scanline->y = outline->y_max - i;

		for (int j = 0; j < outline->num_contours; j++) {
			TTF_Contour *contour = &outline->contours[j];
			int k;
			for (k = 0; k < contour->num_segments; k++) {
				TTF_Segment *segment = &contour->segments[k];
				intersect_segment(segment, scanline);
			}
		}

		/* Round pixel intersection values to 1/64 of a pixel. */
		for (int j = 0; j < scanline->num_intersections; j++) {
			scanline->x[j] = round_pixel(scanline->x[j]);
		}

		/* Sort intersections from left to right. */
		qsort(scanline->x, scanline->num_intersections, sizeof(*scanline->x), cmp_intersections);

//		printf("Intersections: ");
//		char *sep = "";
//		for (int j = 0; j < scanline->num_intersections; j++) {
//			printf("%s%f", sep, scanline->x[j]);
//			sep = ", ";
//		}
//		printf("\n");

		int int_index = 0, fill = 0;
		for (int j = 0; j < bitmap->w; j++) {
			if (int_index < scanline->num_intersections) {
				if ((outline->x_min + j) >= scanline->x[int_index]) {
					fill = !fill;

					/* Skip over duplicate intersections. */
					int k;
					for (k = 1; int_index+k < scanline->num_intersections; k++) {
						if (scanline->x[int_index] != scanline->x[int_index+k]) {
							break;
						}
					}
					int_index += k;
				}
			}
			if (fill) {
				bitmap_set(bitmap, j, i, fg);
			}
		}
	}

	if (font->raster_flags & RENDER_FPAA) {
		/* Downsample intermediate bitmap. */
		for (int y = 0; y < glyph->bitmap->h; y++) {
			for (int x = 0; x < glyph->bitmap->w; x++) {
				/* Calculate pixel coverage:
				 * 	coverage = number filled samples / number samples */
				float coverage = 0;
				if (bitmap_get(bitmap, (2*x), (2*y)) == 0x000000) coverage++;
				if (bitmap_get(bitmap, (2*x)+1, (2*y)) == 0x000000) coverage++;
				if (bitmap_get(bitmap, (2*x), (2*y)+1) == 0x000000) coverage++;
				if (bitmap_get(bitmap, (2*x)+1, (2*y)+1) == 0x000000) coverage++;
				coverage /= 4;
				uint8_t shade = 0xFF*(1-coverage);
				uint32_t pixel = (shade << 16) | (shade << 8) | (shade << 0);

				bitmap_set(glyph->bitmap, x, y, pixel);
			}
		}

		free_bitmap(bitmap);
	} else if (font->raster_flags & RENDER_ASPAA) {
		/* Perform five element low-pass filter. */
		TTF_Bitmap *temp = create_bitmap(bitmap->w, bitmap->h, bg);

		for (int y = 0; y < bitmap->h; y++) {
			for (int x = 0; x < bitmap->w; x++) {
				uint32_t pixel = 0x000000;

				pixel += bitmap_get(bitmap, x-2, y) * (1.0 / 9.0);
				pixel += bitmap_get(bitmap, x-1, y) * (2.0 / 9.0);
				pixel += bitmap_get(bitmap, x, y) * (3.0 / 9.0);
				pixel += bitmap_get(bitmap, x+1, y) * (2.0 / 9.0);
				pixel += bitmap_get(bitmap, x+2, y) * (1.0 / 9.0);

				bitmap_set(temp, x, y, pixel);
			}
		}

		free_bitmap(bitmap);
		bitmap = temp;

		/* Downsample intermediate bitmap. */
		for (int y = 0; y < glyph->bitmap->h; y++) {
			for (int x = 0; x < glyph->bitmap->w; x++) {
				uint8_t r, g, b;
				r = (bitmap_get(bitmap, (3*x), y) * 0xFF) / 0xFFFFFF;
				g = (bitmap_get(bitmap, (3*x)+1, y) * 0xFF) / 0xFFFFFF;
				b = (bitmap_get(bitmap, (3*x)+2, y) * 0xFF) / 0xFFFFFF;
				uint32_t pixel = (r << 16) | (g << 8) | (b << 0);

				bitmap_set(glyph->bitmap, x, y, pixel);
			}
		}

		free_bitmap(bitmap);
	}

	RETRELEASE(free_scanlines(scanlines, num_scanlines));
}