static bool wipcell_add_bezier( fd_Outline o, fd_Outline u, uint i, uint j, uint contour_index, fd_WIPCell cell) { bool ret = true; uint ucontour_begin = u.contours[(int)contour_index].begin; if (cell.to != uint.MaxValue && cell.to != j) { Debug.Assert(cell.to < j); if (cell.from == ucontour_begin) { Debug.Assert(cell.to % 2 == 0); Debug.Assert(cell.from % 2 == 0); cell.start_len = (cell.to - cell.from) / 2; } else { cell.value = cell_add_range(cell.value, cell.from, cell.to); if (cell.value == 0) { ret = false; } } cell.from = j; } else { if (cell.from == uint.MaxValue) { cell.from = j; } } cell.to = j + 2; return(ret); }
static bool for_each_wipcell_finish_contour( fd_Outline o, fd_Outline u, uint contour_index, fd_WIPCell[] cells, ref uint max_start_len) { bool ret = true; for (uint y = 0; y < o.cell_count_y; y++) { for (uint x = 0; x < o.cell_count_x; x++) { fd_WIPCell cell = cells[y * o.cell_count_x + x]; ret &= wipcell_finish_contour(o, u, contour_index, cell, ref max_start_len); } } return(ret); }
static bool try_to_fit_in_cell_count( fd_Outline original, out fd_Outline replacement) { bool ret = true; var cells = new fd_WIPCell[original.cell_count_x * original.cell_count_y]; init_wipcells(original, cells); var temp = new fd_Outline { bbox = original.bbox, cell_count_x = original.cell_count_x, cell_count_y = original.cell_count_y, }; var num_of_contours = original.contours.Count; for (uint contour_index = 0; contour_index < num_of_contours; contour_index++) { uint contour_begin = original.contours[(int)contour_index].begin; uint contour_end = original.contours[(int)contour_index].end; temp.outline_add_odd_point(); var urange = new fd_ContourRange { begin = temp.num_of_points, end = temp.num_of_points + contour_end - contour_begin }; temp.add_outline_contour(urange); for (uint i = contour_begin; i < contour_end; i += 2) { var p0 = original.points[(int)i]; var p1 = original.points[(int)(i + 1)]; //float *p2 = o.points[i + 2]; uint j = temp.num_of_points; temp.add_outline_point(p0); temp.add_outline_point(p1); ret &= for_each_wipcell_add_bezier(original, temp, i, j, contour_index, cells); } uint max_start_len = 0; ret &= for_each_wipcell_finish_contour(original, temp, contour_index, cells, ref max_start_len); uint continuation_end = contour_begin + max_start_len * 2; for (uint i = contour_begin; i < continuation_end; i += 2) { temp.add_outline_point(original.points[(int)i]); temp.add_outline_point(original.points[(int)(i + 1)]); } var plast = original.points[(int)continuation_end]; temp.add_outline_point(plast); } if (!ret) { temp.fd_outline_destroy(); replacement = null; return(ret); } uint filled_line = outline_add_filled_line(temp); uint filled_cell = make_cell_from_single_edge(filled_line); set_filled_cells(temp, cells, filled_cell); copy_wipcell_values(temp, ref cells); original.fd_outline_destroy(); replacement = temp; return(ret); }
static bool wipcell_finish_contour( fd_Outline o, fd_Outline u, uint contour_index, fd_WIPCell cell, ref uint max_start_len) { bool ret = true; uint ucontour_begin = u.contours[(int)contour_index].begin; uint ucontour_end = u.contours[(int)contour_index].end; // max_start_len = uint.MinValue; if (cell.to < ucontour_end) { cell.value = cell_add_range(cell.value, cell.from, cell.to); if (cell.value == 0) { ret = false; } cell.from = uint.MaxValue; cell.to = uint.MaxValue; } Debug.Assert(cell.to == uint.MaxValue || cell.to == ucontour_end); cell.to = uint.MaxValue; if (cell.from != uint.MaxValue && cell.start_len != 0) { cell.value = cell_add_range(cell.value, cell.from, ucontour_end + cell.start_len * 2); if (cell.value == 0) { ret = false; } max_start_len = Math.Max(max_start_len, cell.start_len); cell.from = uint.MaxValue; cell.start_len = 0; } if (cell.from != uint.MaxValue) { cell.value = cell_add_range(cell.value, cell.from, ucontour_end); if (cell.value == 0) { ret = false; } cell.from = uint.MaxValue; } if (cell.start_len != 0) { cell.value = cell_add_range(cell.value, ucontour_begin, ucontour_begin + cell.start_len * 2); if (cell.value == 0) { ret = false; } cell.start_len = 0; } Debug.Assert(cell.from == uint.MaxValue && cell.to == uint.MaxValue); return(ret); }