/* * frame.c * * Copyright © 2013 Thomas White * * This file is part of Colloquium. * * Colloquium is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include "sc_parse.h" #include "frame.h" #include "wrap.h" #include "boxvec.h" static int alloc_ro(struct frame *fr) { struct frame **new_ro; new_ro = realloc(fr->children, fr->max_children*sizeof(struct frame *)); if ( new_ro == NULL ) return 1; fr->children = new_ro; return 0; } struct frame *frame_new() { struct frame *n; n = calloc(1, sizeof(struct frame)); if ( n == NULL ) return NULL; n->children = NULL; n->max_children = 32; if ( alloc_ro(n) ) { fprintf(stderr, "Couldn't allocate children\n"); free(n); return NULL; } n->num_children = 0; n->scblocks = NULL; n->n_paragraphs = 0; n->paragraphs = NULL; n->paragraph_start_lines = NULL; n->lines = NULL; n->n_lines = 0; n->boxes = bv_new(); return n; } void frame_free(struct frame *fr) { int i; if ( fr == NULL ) return; /* Free all lines */ for ( i=0; in_lines; i++ ) { wrap_line_free(&fr->lines[i]); } free(fr->lines); /* Free paragraphs */ if ( fr->paragraphs != NULL ) { for ( i=0; in_paragraphs; i++ ) { free(fr->paragraphs[i]->boxes); free(fr->paragraphs[i]); } free(fr->paragraphs); } /* Free unwrapped boxes */ if ( fr->boxes != NULL ) { free(fr->boxes->boxes); free(fr->boxes); } /* Free all children */ for ( i=0; inum_children; i++ ) { frame_free(fr->children[i]); } free(fr->children); free(fr); } struct frame *add_subframe(struct frame *fr) { struct frame *n; n = frame_new(); if ( n == NULL ) return NULL; if ( fr->num_children == fr->max_children ) { fr->max_children += 32; if ( alloc_ro(fr) ) return NULL; } fr->children[fr->num_children++] = n; return n; } void show_hierarchy(struct frame *fr, const char *t) { int i; char tn[1024]; strcpy(tn, t); strcat(tn, " "); printf("%s%p (%.2f x %.2f)\n", t, fr, fr->w, fr->h); for ( i=0; inum_children; i++ ) { show_hierarchy(fr->children[i], tn); } } static struct frame *find_parent(struct frame *fr, struct frame *search) { int i; for ( i=0; inum_children; i++ ) { if ( fr->children[i] == search ) { return fr; } } for ( i=0; inum_children; i++ ) { struct frame *tt; tt = find_parent(fr->children[i], search); if ( tt != NULL ) return tt; } return NULL; } void delete_subframe(struct frame *top, struct frame *fr) { struct frame *parent; int i, idx, found; parent = find_parent(top, fr); if ( parent == NULL ) { fprintf(stderr, "Couldn't find parent when deleting frame.\n"); return; } found = 0; for ( i=0; inum_children; i++ ) { if ( parent->children[i] == fr ) { idx = i; found = 1; break; } } if ( !found ) { fprintf(stderr, "Couldn't find child when deleting frame.\n"); return; } for ( i=idx; inum_children-1; i++ ) { parent->children[i] = parent->children[i+1]; } parent->num_children--; } struct frame *find_frame_with_scblocks(struct frame *fr, SCBlock *scblocks) { int i; if ( fr->scblocks == scblocks ) return fr; for ( i=0; inum_children; i++ ) { struct frame *tt; tt = find_frame_with_scblocks(fr->children[i], scblocks); if ( tt != NULL ) return tt; } return NULL; }