示例#1
0
	void add_intersection(Line line, bg::model::segment<bpoint> seg,
			std::vector<bpoint> &intersections) {
		bpoint intersect;
		if (intersect_segment(line, seg, intersect)) {

			//We must remove the intersection point
			//if at + and -epsilon not in detector OR
			// if at + and - epsilon in detector

			const double epsilon = 0.001;

			//bpoint temp = line.get_direction_vector();
			//bpoint eps_direction_vec = Utils::mul_coords_by_const(
			//		temp, epsilon);
			bpoint eps_direction_vec = line.get_direction_vector();
			bg::multiply_value(eps_direction_vec, epsilon);
			bpoint before(intersect.get<0>() - eps_direction_vec.get<0>(),
					intersect.get<1>() - eps_direction_vec.get<1>());
			bpoint after = intersect;
			bg::add_point(after, eps_direction_vec);

			bool before_in_det = is_point_inside_geometry(before);
			bool after_in_det = is_point_inside_geometry(after);

			bool is_a_cross_boundary_point = !((before_in_det && after_in_det)
					|| (!before_in_det && !after_in_det));

			if (is_a_cross_boundary_point) {
				intersections.push_back(intersect);
			}
		}
	}
示例#2
0
文件: polygon.c 项目: 31415us/modules
/* Is segment crossing polygon? (including edges)
 *  0 don't cross
 *  1 cross
 *  2 on a side
 *  3 touch out (a segment boundary is on a polygon edge, 
 *  and the second segment boundary is out of the polygon)
 */
uint8_t 
is_crossing_poly(point_t p1, point_t p2, point_t *intersect_pt,
		 poly_t *pol)
{
	uint8_t i;
	uint8_t ret;
	point_t p;
	uint8_t ret1, ret2;
	uint8_t cpt=0;
	
	debug_printf("%" PRIi32 " %" PRIi32 " -> %" PRIi32 " %" PRIi32 " crossing poly %p ?\n", 
	       p1.x, p1.y, p2.x, p2.y, pol);
	debug_printf("poly is : ");
	for (i=0; i<pol->l; i++) {
		debug_printf("%" PRIi32 ",%" PRIi32 " ", pol->pts[i].x, pol->pts[i].y);
	}
	debug_printf("\n");

	for (i=0;i<pol->l;i++) {
		ret = intersect_segment(&p1, &p2, &pol->pts[i], &pol->pts[(i+1)%pol->l], &p);
		debug_printf("%" PRIi32 ",%" PRIi32 " -> %" PRIi32 ",%" PRIi32 
			     " return %d\n", pol->pts[i].x, pol->pts[i].y, 
		       pol->pts[(i+1)%pol->l].x, pol->pts[(i+1)%pol->l].y, ret);


		switch(ret) {
		case 0:
			break;
		case 1:
			if (intersect_pt)
				*intersect_pt = p;
			return 1;
			break;
		case 2:
			cpt++;
			if (intersect_pt)
				*intersect_pt = p;

			break;
		case 3:
			if (intersect_pt)
				*intersect_pt = p;
			return 2;
			break;
		}
	}

	if (cpt==3 ||cpt==4)
		return 1;

	ret1 = is_in_poly(&p1, pol);
	ret2 = is_in_poly(&p2, pol);

	debug_printf("is in poly: p1 %d p2: %d cpt %d\r\n", ret1, ret2, cpt);

	debug_printf("p intersect: %"PRIi32" %"PRIi32"\r\n", p.x, p.y);


	if (cpt==0) {
		if (ret1==1 || ret2==1)
			return 1;
		return 0;
	}


	if (cpt==1) {
		if (ret1==1 || ret2==1)
			return 1;
		return 3;
	}
	if (cpt==2) {
		if (ret1==1 || ret2==1)
			return 1;
		if (ret1==0 || ret2==0)
			return 3;
		return 1;
	}
	
	return 1;
}
示例#3
0
文件: scan.c 项目: 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));
}