• Skip to content
  • Skip to link menu
KDE 3.5 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

kviewshell

GRect.cpp

Go to the documentation of this file.
00001 //C-  -*- C++ -*-
00002 //C- -------------------------------------------------------------------
00003 //C- DjVuLibre-3.5
00004 //C- Copyright (c) 2002  Leon Bottou and Yann Le Cun.
00005 //C- Copyright (c) 2001  AT&T
00006 //C-
00007 //C- This software is subject to, and may be distributed under, the
00008 //C- GNU General Public License, Version 2. The license should have
00009 //C- accompanied the software or you may obtain a copy of the license
00010 //C- from the Free Software Foundation at http://www.fsf.org .
00011 //C-
00012 //C- This program is distributed in the hope that it will be useful,
00013 //C- but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 //C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 //C- GNU General Public License for more details.
00016 //C- 
00017 //C- DjVuLibre-3.5 is derived from the DjVu(r) Reference Library
00018 //C- distributed by Lizardtech Software.  On July 19th 2002, Lizardtech 
00019 //C- Software authorized us to replace the original DjVu(r) Reference 
00020 //C- Library notice by the following text (see doc/lizard2002.djvu):
00021 //C-
00022 //C-  ------------------------------------------------------------------
00023 //C- | DjVu (r) Reference Library (v. 3.5)
00024 //C- | Copyright (c) 1999-2001 LizardTech, Inc. All Rights Reserved.
00025 //C- | The DjVu Reference Library is protected by U.S. Pat. No.
00026 //C- | 6,058,214 and patents pending.
00027 //C- |
00028 //C- | This software is subject to, and may be distributed under, the
00029 //C- | GNU General Public License, Version 2. The license should have
00030 //C- | accompanied the software or you may obtain a copy of the license
00031 //C- | from the Free Software Foundation at http://www.fsf.org .
00032 //C- |
00033 //C- | The computer code originally released by LizardTech under this
00034 //C- | license and unmodified by other parties is deemed "the LIZARDTECH
00035 //C- | ORIGINAL CODE."  Subject to any third party intellectual property
00036 //C- | claims, LizardTech grants recipient a worldwide, royalty-free, 
00037 //C- | non-exclusive license to make, use, sell, or otherwise dispose of 
00038 //C- | the LIZARDTECH ORIGINAL CODE or of programs derived from the 
00039 //C- | LIZARDTECH ORIGINAL CODE in compliance with the terms of the GNU 
00040 //C- | General Public License.   This grant only confers the right to 
00041 //C- | infringe patent claims underlying the LIZARDTECH ORIGINAL CODE to 
00042 //C- | the extent such infringement is reasonably necessary to enable 
00043 //C- | recipient to make, have made, practice, sell, or otherwise dispose 
00044 //C- | of the LIZARDTECH ORIGINAL CODE (or portions thereof) and not to 
00045 //C- | any greater extent that may be necessary to utilize further 
00046 //C- | modifications or combinations.
00047 //C- |
00048 //C- | The LIZARDTECH ORIGINAL CODE is provided "AS IS" WITHOUT WARRANTY
00049 //C- | OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
00050 //C- | TO ANY WARRANTY OF NON-INFRINGEMENT, OR ANY IMPLIED WARRANTY OF
00051 //C- | MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
00052 //C- +------------------------------------------------------------------
00053 // 
00054 // $Id: GRect.cpp,v 1.10 2003/11/07 22:08:21 leonb Exp $
00055 // $Name: release_3_5_15 $
00056 
00057 #ifdef HAVE_CONFIG_H
00058 # include "config.h"
00059 #endif
00060 #if NEED_GNUG_PRAGMAS
00061 # pragma implementation
00062 #endif
00063 
00064 // -- Implementation of class GRect and GRectMapper
00065 // - Author: Leon Bottou, 05/1997
00066 
00067 
00068 #include "GRect.h"
00069 #include "GException.h"
00070 
00071 
00072 #ifdef HAVE_NAMESPACES
00073 namespace DJVU {
00074 # ifdef NOT_DEFINED // Just to fool emacs c++ mode
00075 }
00076 #endif
00077 #endif
00078 
00079 // -- Local utilities
00080 
00081 static inline int 
00082 imin(int x, int y)
00083 {
00084   if (x < y) 
00085     return x;
00086   else
00087     return y;
00088 }
00089 
00090 static inline int 
00091 imax(int x, int y)
00092 {
00093   if (x > y) 
00094     return x;
00095   else
00096     return y;
00097 }
00098 
00099 static inline void
00100 iswap(int &x, int &y)
00101 {
00102   int tmp = x; x = y; y = tmp;
00103 }
00104 
00105 // -- Class GRect
00106 
00107 int 
00108 operator==(const GRect & r1, const GRect & r2)
00109 {
00110   int isempty1 = r1.isempty();
00111   int isempty2 = r2.isempty();
00112   if (isempty1 || isempty2)
00113     if (isempty1 && isempty2)
00114       return 1;
00115   if ( r1.xmin==r2.xmin && r1.xmax==r2.xmax 
00116        && r1.ymin==r2.ymin && r1.ymax==r2.ymax )
00117     return 1;
00118   return 0;
00119 }
00120 
00121 int 
00122 GRect::inflate(int dx, int dy)
00123 {
00124   xmin -= dx;
00125   xmax += dx;
00126   ymin -= dy;
00127   ymax += dy;
00128   if (! isempty()) 
00129     return 1;
00130   xmin = ymin = xmax = ymax = 0;
00131   return 0;
00132 }
00133 
00134 int 
00135 GRect::translate(int dx, int dy)
00136 {
00137   xmin += dx;
00138   xmax += dx;
00139   ymin += dy;
00140   ymax += dy;
00141   if (! isempty()) 
00142     return 1;
00143   xmin = ymin = xmax = ymax = 0;
00144   return 0;
00145 }
00146 
00147 int  
00148 GRect::intersect(const GRect &rect1, const GRect &rect2)
00149 {
00150   xmin = imax(rect1.xmin, rect2.xmin);
00151   xmax = imin(rect1.xmax, rect2.xmax);
00152   ymin = imax(rect1.ymin, rect2.ymin);
00153   ymax = imin(rect1.ymax, rect2.ymax);
00154   if (! isempty()) 
00155     return 1;
00156   xmin = ymin = xmax = ymax = 0;
00157   return 0;
00158 }
00159 
00160 int  
00161 GRect::recthull(const GRect &rect1, const GRect &rect2)
00162 {
00163   if (rect1.isempty())
00164     {
00165       xmin = rect2.xmin;
00166       xmax = rect2.xmax;
00167       ymin = rect2.ymin;
00168       ymax = rect2.ymax;
00169       return !isempty();
00170     }
00171   if (rect2.isempty())
00172     {
00173       xmin = rect1.xmin;
00174       xmax = rect1.xmax;
00175       ymin = rect1.ymin;
00176       ymax = rect1.ymax;
00177       return !isempty();
00178     }
00179   xmin = imin(rect1.xmin, rect2.xmin);
00180   xmax = imax(rect1.xmax, rect2.xmax);
00181   ymin = imin(rect1.ymin, rect2.ymin);
00182   ymax = imax(rect1.ymax, rect2.ymax);
00183   return 1;
00184 }
00185 
00186 int
00187 GRect::contains(const GRect & rect) const
00188 {
00189    GRect tmp_rect;
00190    tmp_rect.intersect(*this, rect);
00191    return tmp_rect==rect;
00192 }
00193 
00194 void
00195 GRect::scale(float factor)
00196 {
00197     xmin = (int)(((float)xmin) * factor);
00198     ymin = (int)(((float)ymin) * factor);
00199     xmax = (int)(((float)xmax) * factor);
00200     ymax = (int)(((float)ymax) * factor);
00201 }
00202 
00203 void
00204 GRect::scale(float xfactor, float yfactor)
00205 {
00206     xmin = (int)(((float)xmin) * xfactor);
00207     ymin = (int)(((float)ymin) * yfactor);
00208     xmax = (int)(((float)xmax) * xfactor);
00209     ymax = (int)(((float)ymax) * yfactor);
00210 }
00211 // -- Class GRatio
00212 
00213 
00214 inline
00215 GRectMapper::GRatio::GRatio()
00216   : p(0), q(1)
00217 {
00218 }
00219 
00220 inline
00221 GRectMapper::GRatio::GRatio(int p, int q)
00222   : p(p), q(q)
00223 {
00224   if (q == 0) 
00225     G_THROW( ERR_MSG("GRect.div_zero") );
00226   if (p == 0)
00227     q = 1;
00228   if (q < 0)
00229     {
00230       p = -p; 
00231       q = -q; 
00232     }
00233   int gcd = 1;
00234   int g1 = p; 
00235   int g2 = q; 
00236   if (g1 > g2)
00237     {
00238       gcd = g1;
00239       g1 = g2;
00240       g2 = gcd;
00241     }
00242   while (g1 > 0)
00243     {
00244       gcd = g1;
00245       g1 = g2 % g1;
00246       g2 = gcd;
00247     }
00248   p /= gcd;
00249   q /= gcd;
00250 }
00251 
00252 
00253 #ifdef HAVE_LONG_LONG_INT
00254 #define llint_t long long int
00255 #else
00256 #define llint_t long int
00257 #endif
00258 
00259 inline int 
00260 operator*(int n, GRectMapper::GRatio r )
00261 { 
00262   /* [LB] -- This computation is carried out with integers and
00263      rational numbers because it must be exact.  Some lizard changed
00264      it to double and this is wrong.  I suspect they did so because
00265      they encountered overflow issues.  Let's use long long ints. */
00266   llint_t x = (llint_t) n * (llint_t) r.p;
00267   if (x >= 0)
00268     return   ((r.q/2 + x) / r.q);
00269   else
00270     return - ((r.q/2 - x) / r.q);
00271 }
00272 
00273 inline int 
00274 operator/(int n, GRectMapper::GRatio r )
00275 { 
00276   /* [LB] -- See comment in operator*() above. */
00277   llint_t x = (llint_t) n * (llint_t) r.q;
00278   if (x >= 0)
00279     return   ((r.p/2 + x) / r.p);
00280   else
00281     return - ((r.p/2 - x) / r.p);
00282 }
00283 
00284 
00285 // -- Class GRectMapper
00286 
00287 #define MIRRORX  1
00288 #define MIRRORY  2
00289 #define SWAPXY 4
00290 
00291 
00292 GRectMapper::GRectMapper()
00293 : rectFrom(0,0,1,1), 
00294   rectTo(0,0,1,1),
00295   code(0)
00296 {
00297 
00298 }
00299 
00300 void
00301 GRectMapper::clear()
00302 {
00303   rectFrom = GRect(0,0,1,1);
00304   rectTo = GRect(0,0,1,1);
00305   code = 0;
00306 }
00307 
00308 void 
00309 GRectMapper::set_input(const GRect &rect)
00310 {
00311   if (rect.isempty())
00312     G_THROW( ERR_MSG("GRect.empty_rect1") );
00313   rectFrom = rect;
00314   if (code & SWAPXY)
00315   {
00316     iswap(rectFrom.xmin, rectFrom.ymin);
00317     iswap(rectFrom.xmax, rectFrom.ymax);
00318   }
00319   rw = rh = GRatio();
00320 }
00321 
00322 void 
00323 GRectMapper::set_output(const GRect &rect)
00324 {
00325   if (rect.isempty())
00326     G_THROW( ERR_MSG("GRect.empty_rect2") );
00327   rectTo = rect;
00328   rw = rh = GRatio();
00329 }
00330 
00331 void 
00332 GRectMapper::rotate(int count)
00333 {
00334   int oldcode = code;
00335   switch (count & 0x3)
00336     {
00337     case 1:
00338       code ^= (code & SWAPXY) ? MIRRORY : MIRRORX;
00339       code ^= SWAPXY;
00340       break;
00341     case 2:
00342       code ^= (MIRRORX|MIRRORY);
00343       break;
00344     case 3:
00345       code ^= (code & SWAPXY) ? MIRRORX : MIRRORY;
00346       code ^= SWAPXY;
00347       break;
00348     }
00349   if ((oldcode ^ code) & SWAPXY)
00350     { 
00351       iswap(rectFrom.xmin, rectFrom.ymin);
00352       iswap(rectFrom.xmax, rectFrom.ymax);
00353       rw = rh = GRatio();
00354     }
00355 }
00356 
00357 void 
00358 GRectMapper::mirrorx()
00359 {
00360   code ^= MIRRORX;
00361 }
00362 
00363 void 
00364 GRectMapper::mirrory()
00365 {
00366   code ^= MIRRORY;
00367 }
00368 
00369 void
00370 GRectMapper::precalc()
00371 {
00372   if (rectTo.isempty() || rectFrom.isempty())
00373     G_THROW( ERR_MSG("GRect.empty_rect3") );
00374   rw = GRatio(rectTo.width(), rectFrom.width());
00375   rh = GRatio(rectTo.height(), rectFrom.height());
00376 }
00377 
00378 void 
00379 GRectMapper::map(int &x, int &y)
00380 {
00381   int mx = x;
00382   int my = y;
00383   // precalc
00384   if (! (rw.p && rh.p))
00385     precalc();
00386   // swap and mirror
00387   if (code & SWAPXY)
00388     iswap(mx,my);
00389   if (code & MIRRORX)
00390     mx = rectFrom.xmin + rectFrom.xmax - mx;
00391   if (code & MIRRORY)
00392     my = rectFrom.ymin + rectFrom.ymax - my;
00393   // scale and translate
00394   x = rectTo.xmin + (mx - rectFrom.xmin) * rw;
00395   y = rectTo.ymin + (my - rectFrom.ymin) * rh;
00396 }
00397 
00398 void 
00399 GRectMapper::unmap(int &x, int &y)
00400 {
00401   // precalc 
00402   if (! (rw.p && rh.p))
00403     precalc();
00404   // scale and translate
00405   int mx = rectFrom.xmin + (x - rectTo.xmin) / rw;
00406   int my = rectFrom.ymin + (y - rectTo.ymin) / rh;
00407   //  mirror and swap
00408   if (code & MIRRORX)
00409     mx = rectFrom.xmin + rectFrom.xmax - mx;
00410   if (code & MIRRORY)
00411     my = rectFrom.ymin + rectFrom.ymax - my;
00412   if (code & SWAPXY)
00413     iswap(mx,my);
00414   x = mx;
00415   y = my;
00416 }
00417 
00418 void 
00419 GRectMapper::map(GRect &rect)
00420 {
00421   map(rect.xmin, rect.ymin);
00422   map(rect.xmax, rect.ymax);
00423   if (rect.xmin >= rect.xmax)
00424     iswap(rect.xmin, rect.xmax);
00425   if (rect.ymin >= rect.ymax)
00426     iswap(rect.ymin, rect.ymax);
00427 }
00428 
00429 void 
00430 GRectMapper::unmap(GRect &rect)
00431 {
00432   unmap(rect.xmin, rect.ymin);
00433   unmap(rect.xmax, rect.ymax);
00434   if (rect.xmin >= rect.xmax)
00435     iswap(rect.xmin, rect.xmax);
00436   if (rect.ymin >= rect.ymax)
00437     iswap(rect.ymin, rect.ymax);
00438 }
00439 
00440 GRect 
00441 GRectMapper::get_input()
00442 {
00443     return rectFrom;
00444 }
00445 
00446 GRect 
00447 GRectMapper::get_output()
00448 {
00449     return rectTo;
00450 }
00451 
00452 
00453 #ifdef HAVE_NAMESPACES
00454 }
00455 # ifndef NOT_USING_DJVU_NAMESPACE
00456 using namespace DJVU;
00457 # endif
00458 #endif

kviewshell

Skip menu "kviewshell"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members

API Reference

Skip menu "API Reference"
  • kviewshell
Generated for API Reference by doxygen 1.5.9
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal