Index: ttf.c =================================================================== --- ttf.c (revision 32830) +++ ttf.c (revision 32831) @@ -41,6 +41,8 @@ #include "ttf_load.h" #include "str_approx.h" +#include + static const char *ttf_cookie = "ttf importer"; static void str_init(pcb_ttf_stroke_t *s) @@ -69,10 +71,81 @@ #define TRX_(x) RND_MM_TO_COORD((x) * stroke.scale_x) #define TRY_(y) RND_MM_TO_COORD((y) * stroke.scale_y) +static void poly_flush(pcb_ttf_stroke_t *str) +{ + int is_neg = 0; + rnd_polyarea_t *pa; + + if (!str->want_poly || (str->contour == NULL)) + return; + + rnd_poly_contour_pre(str->contour, rnd_true); + if (str->contour->Flags.orient != RND_PLF_DIR) { + rnd_poly_contour_inv(str->contour); + is_neg = 1; + } + + pa = rnd_polyarea_create(); + rnd_polyarea_contour_include(pa, str->contour); + vtp0_append((is_neg ? &str->poly_neg : &str->poly_pos), pa); +rnd_trace("poly append: %d [%f] on %s\n", str->contour->Count, str->contour->area/1000000000.0, is_neg ? "neg" : "pos"); + str->contour = NULL; +} + +static void ttf_poly_emit(rnd_pline_t *pl, void *ctx) +{ + long n; + rnd_vnode_t *v; + pcb_ttf_stroke_t *str = ctx; + pcb_poly_t *p = pcb_font_new_poly_in_sym(str->sym, pl->Count); + +rnd_trace(" emit: %d\n", pl->Count); + for(n = 0, v = pl->head; n < pl->Count; n++, v = v->next) { + p->Points[n].X = v->point[0]; + p->Points[n].Y = v->point[1]; + } +} + +static void poly_apply(pcb_ttf_stroke_t *str) +{ + int p, n; + rnd_trace("poly apply:\n"); + for(p = 0; p < str->poly_pos.used; p++) { + rnd_polyarea_t *pap = str->poly_pos.array[p]; + for(n = 0; n < str->poly_neg.used; n++) { + rnd_polyarea_t *res, *pan = str->poly_neg.array[n]; + if (pan == NULL) continue; + if (rnd_poly_contour_in_contour(pap->contours, pan->contours)) { + str->poly_pos.array[n] = NULL; + rnd_polyarea_boolean_free(pap, pan, &res, RND_PBO_SUB); + pap = res; + str->poly_neg.array[n] = NULL; /* already freed, do not reuse */ + } + } + str->poly_pos.array[p] = pap; /* may have changed during the poly bool ops */ + } + + /* dice and free positive poly areas */ + for(p = 0; p < str->poly_pos.used; p++) + rnd_polyarea_no_holes_dicer(str->poly_pos.array[p], -RND_MAX_COORD, -RND_MAX_COORD, +RND_MAX_COORD, +RND_MAX_COORD, ttf_poly_emit, str); + + /* free remaining (unused) negative areas */ + for(n = 0; n < str->poly_neg.used; n++) { + rnd_polyarea_t *pan = str->poly_neg.array[n]; + if (pan != NULL) + rnd_polyarea_free(&pan); + } + + vtp0_uninit(&str->poly_pos); + vtp0_uninit(&str->poly_neg); + rnd_trace("(end)\n"); +} + static int str_move_to(const FT_Vector *to, void *s_) { pcb_ttf_stroke_t *str = s_; rnd_trace(" move %f;%f %ld;%ld\n", str->x, str->y, to->x, to->y); + poly_flush(str); str->x = to->x; str->y = to->y; return 0; @@ -82,10 +155,23 @@ { pcb_ttf_stroke_t *str = s_; rnd_trace(" line %f;%f %ld;%ld\n", str->x, str->y, to->x, to->y); - pcb_font_new_line_in_sym(str->sym, - TRX(str->x), TRY(str->y), - TRX(to->x), TRY(to->y), - 1); + if (str->want_poly) { + rnd_vector_t v; + + + if (str->contour == NULL) { + v[0] = TRX(str->x); v[1] = TRY(str->y); + str->contour = rnd_poly_contour_new(v); + } + v[0] = TRX(to->x); v[1] = TRY(to->y); + rnd_poly_vertex_include(str->contour->head->prev, rnd_poly_node_create(v)); + } + else { + pcb_font_new_line_in_sym(str->sym, + TRX(str->x), TRY(str->y), + TRX(to->x), TRY(to->y), + 1); + } str->x = to->x; str->y = to->y; return 0; @@ -122,13 +208,20 @@ stroke.sym = &f->Symbol['A']; stroke.ttf = &ctx; + stroke.want_poly = 1; + pcb_font_free_symbol(stroke.sym); r = pcb_ttf_trace(&ctx, 'A', 'A', &stroke, 1); rnd_trace("ttf trace; %d\n", r); + + if (stroke.want_poly) { + poly_flush(&stroke); + poly_apply(&stroke); + } + stroke.sym->Valid = 1; - stroke.sym->Width = TRX_(ctx.face->glyph->advance.x); stroke.sym->Height = TRY_(ctx.face->ascender + ctx.face->descender); stroke.sym->Delta = RND_MIL_TO_COORD(12); Index: ttf_load.h =================================================================== --- ttf_load.h (revision 32830) +++ ttf_load.h (revision 32831) @@ -29,9 +29,16 @@ #ifndef PCB_TTF_LOAD_H #define PCB_TTF_LOAD_H +#include "config.h" + #include #include +#include +#include +#include +#include + #include "font.h" typedef struct pcb_ttf_s { @@ -53,6 +60,12 @@ double dx, dy, scale_x, scale_y; pcb_symbol_t *sym; pcb_ttf_t *ttf; + + + unsigned want_poly:1; + + vtp0_t poly_pos, poly_neg; /* of (rnd_polyarea_t *) */ + rnd_pline_t *contour; }; /* Load the ttf font from fn; return 0 on success */