"Fossies" - the Fresh Open Source Software Archive

Member "ivtools-ivtools-2.0.4/src/InterViews/alloctbl.c" (9 Oct 2020, 6512 Bytes) of package /linux/misc/ivtools-ivtools-2.0.4.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "alloctbl.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * Copyright (c) 1991 Stanford University
    3  * Copyright (c) 1991 Silicon Graphics, Inc.
    4  *
    5  * Permission to use, copy, modify, distribute, and sell this software and 
    6  * its documentation for any purpose is hereby granted without fee, provided
    7  * that (i) the above copyright notices and this permission notice appear in
    8  * all copies of the software and related documentation, and (ii) the names of
    9  * Stanford and Silicon Graphics may not be used in any advertising or
   10  * publicity relating to the software without the specific, prior written
   11  * permission of Stanford and Silicon Graphics.
   12  * 
   13  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
   14  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
   15  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
   16  *
   17  * IN NO EVENT SHALL STANFORD OR SILICON GRAPHICS BE LIABLE FOR
   18  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
   19  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
   20  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
   21  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
   22  * OF THIS SOFTWARE.
   23  */
   24 
   25 /*
   26  * AllocationInfo - common information stored for allocations
   27  */
   28 
   29 #include <InterViews/alloctbl.h>
   30 #include <InterViews/canvas.h>
   31 #include <OS/list.h>
   32 #include <OS/math.h>
   33 
   34 /*
   35  * An allocation table is represented by a list of pointers to
   36  * allocation information objects.  The list is ordered by usage
   37  * from least recently used to most recently used.  Whenever a lookup
   38  * is done on the table that finds the information for a <canvas, allocation>
   39  * pair, the pointer to the information is removed from its current position
   40  * in the list and put at the end.  In the common case where the list
   41  * has a single element, moving the found element is unnecessary.
   42  */
   43 
   44 declarePtrList(AllocationInfoList,AllocationInfo)
   45 implementPtrList(AllocationInfoList,AllocationInfo)
   46 
   47 class AllocationTableImpl {
   48 private:
   49     friend class AllocationTable;
   50 
   51     AllocationTableImpl(GlyphIndex, long);
   52 
   53     static boolean equal(const Allocation&, const Allocation&);
   54     static boolean same_size(const Allotment&, const Allotment&);
   55 
   56     GlyphIndex count_;
   57     long maximum_allocations_;
   58     AllocationInfoList allocations_;
   59     static const float epsilon_;
   60 };
   61 
   62 const float AllocationTableImpl::epsilon_ = 1e-4;
   63 
   64 AllocationTableImpl::AllocationTableImpl(
   65     GlyphIndex count, long maximum
   66 ) : count_(count), maximum_allocations_(maximum), allocations_(maximum) { }
   67 
   68 inline boolean AllocationTableImpl::equal(
   69     const Allocation& a1, const Allocation& a2
   70 ) {
   71     return a1.equals(a2, epsilon_);
   72 }
   73 
   74 inline boolean AllocationTableImpl::same_size(
   75     const Allotment& a1, const Allotment& a2
   76 ) {
   77     return (
   78     Math::equal(a1.span(), a2.span(), epsilon_) &&
   79     Math::equal(a1.alignment(), a2.alignment(), epsilon_)
   80     );
   81 }
   82 
   83 AllocationTable::AllocationTable(GlyphIndex count, long maximum_allocations) {
   84     impl_ = new AllocationTableImpl(count, maximum_allocations);
   85 }
   86 
   87 AllocationTable::~AllocationTable() {
   88     flush();
   89     delete impl_;
   90 }
   91 
   92 /*
   93  * Find an element on the list that matches the given canvas and allocation.
   94  */
   95 
   96 AllocationInfo* AllocationTable::find(Canvas* c, const Allocation& a) const {
   97     AllocationInfoList& list = impl_->allocations_;
   98     for (ListUpdater(AllocationInfoList) i(list); i.more(); i.next()) {
   99     AllocationInfo* info = i.cur();
  100     if (info->canvas_ == c &&
  101         (c == nil || *info->transformer_ == c->transformer()) &&
  102         AllocationTableImpl::equal(info->allocation_, a)
  103     ) {
  104         if (list.count() > 1) {
  105         i.remove_cur();
  106         list.append(info);
  107         }
  108         return info;
  109     }
  110     }
  111     return nil;
  112 }
  113 
  114 /*
  115  * Find an element on the list with the same canvas and same size
  116  * allocation as given.  If found, set the difference in the position
  117  * of the new allocation's origin to dx and dy.
  118  */
  119 
  120 AllocationInfo* AllocationTable::find_same_size(
  121     Canvas* c, const Allocation& a, Coord& dx, Coord& dy
  122 ) const {
  123     const Allotment& x = a.x_allotment();
  124     const Allotment& y = a.y_allotment();
  125     AllocationInfoList& list = impl_->allocations_;
  126     for (ListUpdater(AllocationInfoList) i(list); i.more(); i.next()) {
  127     AllocationInfo* info = i.cur();
  128     if (info->canvas_ == c &&
  129         (c == nil || *info->transformer_ == c->transformer())
  130     ) {
  131         Allotment& oldx = info->allocation_.x_allotment();
  132         Allotment& oldy = info->allocation_.y_allotment();
  133         if (AllocationTableImpl::same_size(x, oldx) &&
  134         AllocationTableImpl::same_size(y, oldy)
  135         ) {
  136         dx = x.origin() - oldx.origin();
  137         dy = y.origin() - oldy.origin();
  138         oldx.origin(x.origin());
  139         oldy.origin(y.origin());
  140         if (list.count() > 1) {
  141             i.remove_cur();
  142             list.append(info);
  143         }
  144         return info;
  145         }
  146         }
  147     }
  148     return nil;
  149 }
  150 
  151 /*
  152  * Allocate a new table entry for the given canvas and allocation.
  153  * If the table is full, then use the first (least recently used) entry.
  154  */
  155 
  156 AllocationInfo* AllocationTable::allocate(Canvas* c, const Allocation& a) {
  157     AllocationInfo* info;
  158     AllocationInfoList& list = impl_->allocations_;
  159     if (list.count() < impl_->maximum_allocations_) {
  160     info = new AllocationInfo;
  161     info->transformer_ = new Transformer;
  162     if (impl_->count_ == 0) {
  163         info->component_allocation_ = nil;
  164     } else {
  165         info->component_allocation_ = new Allocation[impl_->count_];
  166     }
  167     } else {
  168     info = list.item(0);
  169     list.remove(0);
  170     }
  171     info->canvas_ = c;
  172     if (c == nil) {
  173     /*
  174      * This case shouldn't happen, but some old code (doc)
  175      * occasionally passes nil for the canvas during allocation.
  176      */
  177     Transformer t;
  178     *info->transformer_ = t;
  179     } else {
  180     *info->transformer_ = c->transformer();
  181     }
  182     info->allocation_ = a;
  183     list.append(info);
  184     return info;
  185 }
  186 
  187 /*
  188  * Return the most recently used allocation information, if any.
  189  */
  190 
  191 AllocationInfo* AllocationTable::most_recent() const {
  192     AllocationInfo* info = nil;
  193     AllocationInfoList& list = impl_->allocations_;
  194     long n = list.count();
  195     if (n != 0) {
  196     info = list.item(n - 1);
  197     }
  198     return info;
  199 }
  200 
  201 /*
  202  * Flush all the entries from the table.
  203  */
  204 
  205 void AllocationTable::flush() {
  206     AllocationInfoList& list = impl_->allocations_;
  207     for (ListItr(AllocationInfoList) i(list); i.more(); i.next()) {
  208     AllocationInfo* info = i.cur();
  209     if (info->component_allocation_ != nil) {
  210         delete [] info->component_allocation_;
  211     }
  212     delete info->transformer_;
  213     delete info;
  214     }
  215     list.remove_all();
  216 }