31 const int k1 = *(
int *)v1;
32 const int k2 = *(
int *)v2;
43 XLabels_t *xlp =
gv_alloc(
sizeof(XLabels_t));
47 fprintf(stderr,
"out of memory\n");
74 double maxx = obj_bb.
UR.
x, maxy = obj_bb.
UR.
y;
75 return (
unsigned)floor(log2(round(fmax(maxx, maxy)))) + 1;
111 int x = p.
x, y = p.
y;
114 for (
unsigned i = n - 1; n > 0; i--) {
115 int xi = (x >> i) & 1;
116 int yi = (y >> i) & 1;
117 s = 4 *
s + 2 * (unsigned)xi +
118 ((
unsigned)xi ^ (unsigned)yi);
121 y = y ^ (x & (yi - 1));
123 x = x ^ (-xi & (yi - 1));
124 y = y ^ (-xi & (yi - 1));
144 double iminx = fmax(r.
boundary[0],
s.boundary[0]);
146 double iminy = fmax(r.
boundary[1],
s.boundary[1]);
148 double imaxx = fmin(r.
boundary[2],
s.boundary[2]);
150 double imaxy = fmin(r.
boundary[3],
s.boundary[3]);
151 return (imaxx - iminx) * (imaxy - iminy);
161 assert(objp1->
sz.
x == 0 && objp1->
sz.
y == 0);
213 if (!lp->
set || !clp->set)
215 if ((op->
pos.
x == 0.0 && op->
pos.
y == 0.0) ||
216 (cp->
pos.
x == 0.0 && cp->
pos.
y == 0.0))
247 if (intrsx[i] !=
NULL) {
248 double sa, maxa = 0.0;
255 if (intrsx[i]->lbl) {
259 maxa = fmax(sa, maxa);
277 if (intrsx[i] !=
NULL) {
278 double sa, maxa = 0.0;
285 if (intrsx[i]->lbl) {
289 maxa = fmax(sa, maxa);
306 BestPos_t bp = {.pos = objp->
lbl->
pos};
308 for (
size_t i = 0; i < xlp->n_objs; i++) {
309 if (objp == &xlp->objs[i])
311 if (xlp->objs[i].sz.x > 0 && xlp->objs[i].sz.y > 0)
361 double xincr = (2 * lp->
sz.
x + objp->
sz.
x) / XLXDENOM;
362 double yincr = (2 * lp->
sz.
y + objp->
sz.
y) / XLYDENOM;
379 if (nbp.area < bp.area)
386 if (nbp.area < bp.area)
396 if (nbp.area < bp.area)
403 if (nbp.area < bp.area)
413 if (nbp.area < bp.area)
420 if (nbp.area < bp.area)
427 if (nbp.area < bp.area)
431 if (intrsx[XLPXNY] || intrsx[XLCXNY] || intrsx[XLNXNY] || intrsx[XLPXCY] ||
433 if (!intrsx[XLCXNY] && !intrsx[XLNXNY]) {
441 if (nbp.area < bp.area)
445 if (!intrsx[XLPXCY] && !intrsx[XLPXPY]) {
453 if (nbp.area < bp.area)
462 if (intrsx[XLNXPY] || intrsx[XLCXPY] || intrsx[XLPXPY] || intrsx[XLNXCY] ||
464 if (!intrsx[XLCXPY] && !intrsx[XLPXPY]) {
472 if (nbp.area < bp.area)
476 if (!intrsx[XLNXCY] && !intrsx[XLNXNY]) {
484 if (nbp.area < bp.area)
497 const unsigned order =
xlhorder(obj_bb);
499 for (
size_t i = 0; i < xlp->n_objs; i++) {
500 HDict_t *hp =
gv_alloc(
sizeof(HDict_t));
502 hp->d.data = &xlp->objs[i];
505 const double x = hp->d.rect.boundary[0] +
506 (hp->d.rect.boundary[2] - hp->d.rect.boundary[0]) / 2;
507 const double y = hp->d.rect.boundary[1] +
508 (hp->d.rect.boundary[3] - hp->d.rect.boundary[1]) / 2;
509 assert(x >= INT_MIN && x <= INT_MAX);
510 assert(y >= INT_MIN && y <= INT_MAX);
511 const point pi = {.
x = (int)x, .y = (
int)y};
522 int size =
dtsize(xlp->hdx), freed = 0;
523 while (
dtsize(xlp->hdx)) {
532 assert(size == freed);
537 for (HDict_t *op =
dtfirst(xlp->hdx); op; op =
dtnext(xlp->hdx, op)) {
539 RTreeInsert(xlp->spdx, op->d.rect, op->d.data, &xlp->spdx->root);
555 XLabels_t *xlp =
xlnew(objs, n_objs);
577 for (
size_t i = 0; i < n_objs; i++) {
578 if (objs[i].lbl == 0)
580 const BestPos_t bp =
xladjust(xlp, &objs[i]);
583 }
else if (bp.area == 0) {
584 objs[i].
lbl->
pos = bp.pos;
586 }
else if (params->
force) {
587 objs[i].
lbl->
pos = bp.pos;
Memory allocation wrappers that exit on failure.
static void * gv_alloc(size_t size)
CDT_API Dtmethod_t * Dtobag
ordered multiset
CDT_API int dtsize(Dt_t *)
CDT_API int dtclose(Dt_t *)
CDT_API Dt_t * dtopen(Dtdisc_t *, Dtmethod_t *)
static NORETURN void graphviz_exit(int status)
void RTreeLeafListFree(LeafList_t *llp)
RTree_t * RTreeOpen(void)
void RTreeClose(RTree_t *rtp)
int RTreeInsert(RTree_t *rtp, Rect_t r, void *data, Node_t **n)
LeafList_t * RTreeSearch(RTree_t *rtp, Node_t *n, Rect_t r)
bool Overlap(const Rect_t r, const Rect_t s)
double boundary[NUMSIDES]
bool force
if true, all labels must be placed
bool set
true if the position has been set (input/output)
static BestPos_t xlintersections(XLabels_t *xlp, object_t *objp, object_t *intrsx[XLNBR])
static double aabbaabb(Rect_t r, Rect_t s)
static double recordlintrsx(object_t *op, object_t *cp, Rect_t *rp, double a, object_t *intrsx[XLNBR])
static unsigned int xlhorder(boxf obj_bb)
static int xlhdxload(XLabels_t *xlp, boxf obj_bb)
static void xlfree(XLabels_t *xlp)
static void xlspdxload(XLabels_t *xlp)
static Rect_t objplp2rect(const object_t *objp)
static Rect_t objp2rect(const object_t *op)
static void xlhdxunload(XLabels_t *xlp)
static double recordointrsx(object_t *op, object_t *cp, Rect_t rp, double a, object_t *intrsx[XLNBR])
static XLabels_t * xlnew(object_t *objs, size_t n_objs)
static int getintrsxi(object_t *op, object_t *cp)
static bool lblenclosing(object_t *objp, object_t *objp1)
static BestPos_t xladjust(XLabels_t *xlp, object_t *objp)
int placeLabels(object_t *objs, size_t n_objs, const label_params_t *params)
static Rect_t objplpmks(object_t *objp)
static unsigned hd_hil_s_from_xy(point p, unsigned n)
static int xlinitialize(XLabels_t *xlp, boxf obj_bb)
static int icompare(void *, void *)