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

kviewshell

GMapAreas.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: GMapAreas.cpp,v 1.9 2004/05/05 15:12:42 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 #include "GMapAreas.h"
00065 #include "GException.h"
00066 #include "debug.h"
00067 
00068 #include <math.h>
00069 #include <stdio.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 
00080 /****************************************************************************
00081 ***************************** GMapArea definition ***************************
00082 ****************************************************************************/
00083 
00084 const char GMapArea::MAPAREA_TAG[] =        "maparea";
00085 const char GMapArea::RECT_TAG[] =       "rect";
00086 const char GMapArea::POLY_TAG[] =       "poly";
00087 const char GMapArea::OVAL_TAG[] =       "oval";
00088 const char GMapArea::NO_BORDER_TAG[] =      "none";
00089 const char GMapArea::XOR_BORDER_TAG[] =     "xor";
00090 const char GMapArea::SOLID_BORDER_TAG[] =   "border";
00091 const char GMapArea::SHADOW_IN_BORDER_TAG[] =   "shadow_in";
00092 const char GMapArea::SHADOW_OUT_BORDER_TAG[] =  "shadow_out";
00093 const char GMapArea::SHADOW_EIN_BORDER_TAG[] =  "shadow_ein";
00094 const char GMapArea::SHADOW_EOUT_BORDER_TAG[] = "shadow_eout";
00095 const char GMapArea::BORDER_AVIS_TAG[] =    "border_avis";
00096 const char GMapArea::HILITE_TAG[] =         "hilite";
00097 const char GMapArea::URL_TAG[] =        "url";
00098 const char GMapArea::TARGET_SELF[] =        "_self";
00099 static const char zero_width[] = ERR_MSG("GMapAreas.zero_width");
00100 static const char zero_height[] = ERR_MSG("GMapAreas.zero_height");
00101 static const char width_1[] = ERR_MSG("GMapAreas.width_1");
00102 static const char width_3_32 [] = ERR_MSG("GMapAreas.width_3-32");
00103 static const char error_poly_border [] = ERR_MSG("GMapAreas.poly_border");
00104 static const char error_poly_hilite [] = ERR_MSG("GMapAreas.poly_hilite");
00105 static const char error_oval_border [] = ERR_MSG("GMapAreas.oval_border");
00106 static const char error_oval_hilite [] = ERR_MSG("GMapAreas.oval_hilite");
00107 static const char error_too_few_points [] = ERR_MSG("GMapAreas.too_few_points");
00108 static const char error_intersect [] = ERR_MSG("GMapAreas.intersect");
00109 
00110 GMapArea::~GMapArea() {}
00111 
00112 GMapRect::~GMapRect() {}
00113 
00114 GMapPoly::~GMapPoly() {}
00115 
00116 GMapOval::~GMapOval() {}
00117 
00118 void
00119 GMapArea::initialize_bounds(void)
00120 {
00121    xmin=gma_get_xmin();
00122    xmax=gma_get_xmax();
00123    ymin=gma_get_ymin();
00124    ymax=gma_get_ymax();
00125    bounds_initialized=true;
00126 }
00127 
00128 int
00129 GMapArea::get_xmin(void) const
00130 {
00131    if (!bounds_initialized)
00132      const_cast<GMapArea *>(this)->initialize_bounds();
00133    return xmin;
00134 }
00135 
00136 int
00137 GMapArea::get_ymin(void) const
00138 {
00139    if (!bounds_initialized)
00140      const_cast<GMapArea *>(this)->initialize_bounds();
00141    return ymin;
00142 }
00143 
00144 int
00145 GMapArea::get_xmax(void) const
00146 {
00147    if (!bounds_initialized)
00148      const_cast<GMapArea *>(this)->initialize_bounds();
00149    return xmax;
00150 }
00151 
00152 int
00153 GMapArea::get_ymax(void) const
00154 {
00155    if (!bounds_initialized)
00156      const_cast<GMapArea *>(this)->initialize_bounds();
00157    return ymax;
00158 }
00159 
00160 GRect
00161 GMapArea::get_bound_rect(void) const
00162 {
00163    return GRect(get_xmin(), get_ymin(), get_xmax()-get_xmin(),
00164         get_ymax()-get_ymin());
00165 }
00166 
00167 void
00168 GMapArea::move(int dx, int dy)
00169 {
00170    if (dx || dy)
00171    {
00172      if (bounds_initialized)
00173      {
00174         xmin+=dx;
00175         ymin+=dy;
00176         xmax+=dx;
00177         ymax+=dy;
00178      }
00179      gma_move(dx, dy);
00180    }
00181 }
00182 
00183 void
00184 GMapArea::resize(int new_width, int new_height)
00185 {
00186    if (get_xmax()-get_xmin()!=new_width ||
00187        get_ymax()-get_ymin()!=new_height)
00188    {
00189      gma_resize(new_width, new_height);
00190      bounds_initialized=false;
00191    }
00192 }
00193 
00194 void
00195 GMapArea::transform(const GRect & grect)
00196 {
00197    if (grect.xmin!=get_xmin() || grect.ymin!=get_ymin() ||
00198        grect.xmax!=get_xmax() || grect.ymax!=get_ymax())
00199    {
00200      gma_transform(grect);
00201      bounds_initialized=false;
00202    }
00203 }
00204 
00205 char const * const
00206 GMapArea::check_object(void)
00207 {
00208    char const *retval;
00209    if (get_xmax()==get_xmin())
00210    {
00211      retval=zero_width;
00212    }
00213    else if (get_ymax()==get_ymin())
00214    {
00215      retval=zero_height;
00216    }
00217    else if ((border_type==XOR_BORDER ||
00218        border_type==SOLID_BORDER) && border_width!=1)
00219    {
00220      retval=width_1;
00221    }
00222    else if ((border_type==SHADOW_IN_BORDER ||
00223        border_type==SHADOW_OUT_BORDER ||
00224        border_type==SHADOW_EIN_BORDER ||
00225        border_type==SHADOW_EOUT_BORDER)&&
00226        (border_width<3 || border_width>32))
00227    {
00228      retval=width_3_32;
00229    }else
00230    {
00231      retval=gma_check_object();
00232    }
00233    return retval;
00234 }
00235 
00236 bool
00237 GMapArea::is_point_inside(int x, int y) const
00238 {
00239    if (!bounds_initialized)
00240      const_cast<GMapArea *>(this)->initialize_bounds();
00241    return (x>=xmin && x<xmax && y>=ymin && y<ymax) ?
00242           gma_is_point_inside(x, y) : false;
00243 }
00244 
00245 GUTF8String
00246 GMapArea::print(void)
00247 {
00248       // Make this hard check to make sure, that *no* illegal GMapArea
00249       // can be stored into a file.
00250    const char * const errors=check_object();
00251    if (errors[0])
00252    {
00253      G_THROW(errors);
00254    }
00255    
00256    int i;
00257    GUTF8String tmp;
00258    GUTF8String url1, target1, comment1;
00259    const GUTF8String url_str=url;
00260    for(i=0;i<(int) url_str.length();i++)
00261    {
00262       char ch=url_str[i];
00263       if (ch=='"')
00264         url1+='\\';
00265       url1+=ch;
00266    }
00267    for(i=0;i<(int) target.length();i++)
00268    {
00269       char ch=target[i];
00270       if (ch=='"')
00271         target1+='\\';
00272       target1+=ch;
00273    }
00274    for(i=0;i<(int) comment.length();i++)
00275    {
00276       char ch=comment[i];
00277       if (ch=='"')
00278         comment1+='\\';
00279       comment1+=ch;
00280    }
00281    
00282    GUTF8String border_color_str;
00283    border_color_str.format("#%02X%02X%02X",
00284        (border_color & 0xff0000) >> 16,
00285        (border_color & 0xff00) >> 8,
00286        (border_color & 0xff));
00287 
00288    static const GUTF8String left('(');
00289    static const GUTF8String right(')');
00290    static const GUTF8String space(' ');
00291    static const GUTF8String quote('"');
00292    GUTF8String border_type_str;
00293    switch(border_type)
00294    {
00295       case NO_BORDER:
00296         border_type_str=left+NO_BORDER_TAG+right;
00297         break;
00298       case XOR_BORDER:
00299         border_type_str=left+XOR_BORDER_TAG+right;
00300         break;
00301       case SOLID_BORDER:
00302         border_type_str=left+SOLID_BORDER_TAG+space+border_color_str+right;
00303         break;
00304       case SHADOW_IN_BORDER:
00305         border_type_str=left+SHADOW_IN_BORDER_TAG+space+GUTF8String(border_width)+right;
00306         break;
00307       case SHADOW_OUT_BORDER:
00308         border_type_str=left+SHADOW_OUT_BORDER_TAG+space+GUTF8String(border_width)+right;
00309         break;
00310       case SHADOW_EIN_BORDER:
00311         border_type_str=left+SHADOW_EIN_BORDER_TAG+space+GUTF8String(border_width)+right;
00312         break;
00313       case SHADOW_EOUT_BORDER:
00314         border_type_str=left+SHADOW_EOUT_BORDER_TAG+space+GUTF8String(border_width)+right;
00315         break;
00316       default:
00317         border_type_str=left+XOR_BORDER_TAG+right;
00318         break;
00319    }
00320 
00321    GUTF8String hilite_str;
00322    if (hilite_color!=0xffffffff)
00323    {
00324       hilite_str.format("(%s #%02X%02X%02X)",
00325           HILITE_TAG, (hilite_color & 0xff0000) >> 16,
00326           (hilite_color & 0xff00) >> 8,
00327           (hilite_color & 0xff));
00328    }
00329    
00330    GUTF8String URL;
00331    if (target1==TARGET_SELF)
00332    {
00333       URL=quote+url1+quote;
00334    }else
00335    {
00336       URL=left+URL_TAG+space+quote+url1+quote+space+quote+target1+quote+right;
00337    }
00338 
00339    GUTF8String total=left+MAPAREA_TAG+space+URL+space+quote+comment1+quote+space+gma_print()+border_type_str;
00340    if (border_always_visible)
00341      total+=space+left+BORDER_AVIS_TAG+right;
00342    if ( hilite_str.length() > 0 )
00343      total+=space+hilite_str;
00344    total+=right;
00345    return total;
00346 }
00347 
00348 /*
00349 void 
00350 GMapArea::map(GRectMapper &mapper)
00351 {
00352     get_bound_rect();
00353     GRect rect = GRect(xmin, ymin, xmax, ymax);
00354     mapper.map(rect);
00355     xmin = rect.xmin;
00356     ymin = rect.ymin;
00357     xmax = rect.xmax;
00358     ymax = rect.ymax;
00359     clear_bounds();
00360 }
00361 void 
00362 GMapArea::unmap(GRectMapper &mapper)
00363 {
00364     get_bound_rect();
00365     GRect rect = GRect(xmin, ymin, xmax, ymax);
00366     mapper.unmap(rect);
00367     xmin = rect.xmin;
00368     ymin = rect.ymin;
00369     xmax = rect.xmax;
00370     ymax = rect.ymax;
00371     clear_bounds();
00372 }
00373 */
00374 
00375 
00378 void GMapArea::get_coords( GList<int> & CoordList ) const
00379 {
00380   CoordList.append( get_xmin() );
00381   CoordList.append( get_ymin() );
00382   CoordList.append( get_xmax() );
00383   CoordList.append( get_ymax() );
00384 }
00385 
00386 
00387 /****************************************************************************
00388 **************************** GMapRect definition ****************************
00389 ****************************************************************************/
00390 
00391 void
00392 GMapRect::gma_resize(int new_width, int new_height)
00393 {
00394    xmax=xmin+new_width;
00395    ymax=ymin+new_height;
00396 }
00397 
00398 void
00399 GMapRect::gma_transform(const GRect & grect)
00400 {
00401    xmin=grect.xmin; ymin=grect.ymin;
00402    xmax=grect.xmax; ymax=grect.ymax;
00403 }
00404 
00405 GUTF8String
00406 GMapRect::gma_print(void)
00407 {
00408    GUTF8String buffer;
00409    return buffer.format("(%s %d %d %d %d) ",
00410        RECT_TAG, xmin, ymin, xmax-xmin, ymax-ymin);
00411 }
00412 
00413 void 
00414 GMapRect::map(GRectMapper &mapper)
00415 {
00416     get_bound_rect();
00417     GRect rect;
00418     rect.xmin = xmin;
00419     rect.xmax = xmax;
00420     rect.ymin = ymin;
00421     rect.ymax = ymax;
00422     mapper.map(rect);
00423     xmin = rect.xmin;
00424     ymin = rect.ymin;
00425     xmax = rect.xmax;
00426     ymax = rect.ymax;
00427     clear_bounds();
00428 }
00429 void 
00430 GMapRect::unmap(GRectMapper &mapper)
00431 {
00432     get_bound_rect();
00433     GRect rect;
00434     rect.xmin = xmin;
00435     rect.xmax = xmax;
00436     rect.ymin = ymin;
00437     rect.ymax = ymax;
00438     mapper.unmap(rect);
00439     xmin = rect.xmin;
00440     ymin = rect.ymin;
00441     xmax = rect.xmax;
00442     ymax = rect.ymax;
00443     clear_bounds();
00444 }
00445 
00446 /****************************************************************************
00447 **************************** GMapPoly definition ****************************
00448 ****************************************************************************/
00449 
00450 inline int
00451 GMapPoly::sign(int x) { return x<0 ? -1 : x>0 ? 1 : 0; }
00452 
00453 bool
00454 GMapPoly::does_side_cross_rect(const GRect & grect, int side)
00455 {
00456    int x1=xx[side], x2=xx[(side+1)%points];
00457    int y1=yy[side], y2=yy[(side+1)%points];
00458    int xmin=x1<x2 ? x1 : x2;
00459    int ymin=y1<y2 ? y1 : y2;
00460    int xmax=x1+x2-xmin;
00461    int ymax=y1+y2-ymin;
00462 
00463    if (xmax<grect.xmin || xmin>grect.xmax ||
00464        ymax<grect.ymin || ymin>grect.ymax) return false;
00465 
00466    return
00467       x1>=grect.xmin && x1<=grect.xmax && y1>=grect.ymin && y1<=grect.ymax ||
00468       x2>=grect.xmin && x2<=grect.xmax && y2>=grect.ymin && y2<=grect.ymax ||
00469       do_segments_intersect(grect.xmin, grect.ymin, grect.xmax, grect.ymax,
00470                 x1, y1, x2, y2) ||
00471       do_segments_intersect(grect.xmax, grect.ymin, grect.xmin, grect.ymax,
00472                 x1, y1, x2, y2);
00473 }
00474 
00475 bool
00476 GMapPoly::is_projection_on_segment(int x, int y, int x1, int y1, int x2, int y2)
00477 {
00478    int res1=(x-x1)*(x2-x1)+(y-y1)*(y2-y1);
00479    int res2=(x-x2)*(x2-x1)+(y-y2)*(y2-y1);
00480    return sign(res1)*sign(res2)<=0;
00481 }
00482 
00483 bool
00484 GMapPoly::do_segments_intersect(int x11, int y11, int x12, int y12,
00485                 int x21, int y21, int x22, int y22)
00486 {
00487    int res11=(x11-x21)*(y22-y21)-(y11-y21)*(x22-x21);
00488    int res12=(x12-x21)*(y22-y21)-(y12-y21)*(x22-x21);
00489    int res21=(x21-x11)*(y12-y11)-(y21-y11)*(x12-x11);
00490    int res22=(x22-x11)*(y12-y11)-(y22-y11)*(x12-x11);
00491    if (!res11 && !res12)
00492    {
00493       // Segments are on the same line
00494       return
00495      is_projection_on_segment(x11, y11, x21, y21, x22, y22) ||
00496      is_projection_on_segment(x12, y12, x21, y21, x22, y22) ||
00497      is_projection_on_segment(x21, y21, x11, y11, x12, y12) ||
00498      is_projection_on_segment(x22, y22, x11, y11, x12, y12);
00499    }
00500    int sign1=sign(res11)*sign(res12);
00501    int sign2=sign(res21)*sign(res22);
00502    return sign1<=0 && sign2<=0;
00503 }
00504 
00505 bool
00506 GMapPoly::are_segments_parallel(int x11, int y11, int x12, int y12,
00507                 int x21, int y21, int x22, int y22)
00508 {
00509    return (x12-x11)*(y22-y21)-(y12-y11)*(x22-x21)==0;
00510 }
00511 
00512 char const * const
00513 GMapPoly::check_data(void)
00514 {
00515   if (open && points<2 || !open && points<3) 
00516     return error_too_few_points;
00517   for(int i=0;i<sides;i++)
00518   {
00519     for(int j=i+2;j<sides;j++)
00520     {
00521       if (i != (j+1)%points )
00522       {
00523         if (do_segments_intersect(xx[i], yy[i], xx[i+1], yy[i+1],
00524                       xx[j], yy[j], xx[(j+1)%points], yy[(j+1)%points]))
00525         {
00526           return error_intersect;
00527         }
00528       }
00529     }
00530   }
00531   return "";
00532 }
00533 
00534 void
00535 GMapPoly::optimize_data(void)
00536 {
00537    // Removing segments of length zero
00538    int i;
00539    for(i=0;i<sides;i++)
00540    {
00541       while(xx[i]==xx[(i+1)%points] && yy[i]==yy[(i+1)%points])
00542       {
00543      for(int k=(i+1)%points;k<points-1;k++)
00544      {
00545         xx[k]=xx[k+1]; yy[k]=yy[k+1];
00546      }
00547      points--; sides--;
00548      if (!points) return;
00549       }
00550    }
00551    // Concatenating consequitive parallel segments
00552    for(i=0;i<sides;i++)
00553    {
00554       while((open && i+1<sides || !open) &&
00555         are_segments_parallel(xx[i], yy[i],
00556                   xx[(i+1)%points], yy[(i+1)%points],
00557                   xx[(i+1)%points], yy[(i+1)%points],
00558                   xx[(i+2)%points], yy[(i+2)%points]))
00559       {
00560      for(int k=(i+1)%points;k<points-1;k++)
00561      {
00562         xx[k]=xx[k+1]; yy[k]=yy[k+1];
00563      }
00564      points--; sides--;
00565      if (!points) return;
00566       }
00567    }
00568 }
00569 
00570 bool
00571 GMapPoly::gma_is_point_inside(const int xin, const int yin) const
00572 {
00573    if (open)
00574      return false;
00575    
00576    int xfar=get_xmax()+(get_xmax()-get_xmin());
00577    
00578    int intersections=0;
00579    for(int i=0;i<points;i++)
00580    {
00581       int res1=yy[i]-yin;
00582       if (!res1) continue;
00583       int res2, isaved=i;
00584       while(!(res2=yy[(i+1)%points]-yin)) i++;
00585       if (isaved!=i)
00586       {
00587      // Some points fell exactly on the line
00588      if ((xx[(isaved+1)%points]-xin)*
00589          (xx[i%points]-xin)<=0)
00590      {
00591         // Test point is exactly on the boundary
00592         return true;
00593      }
00594       }
00595       if (res1<0 && res2>0 || res1>0 && res2<0)
00596       {
00597      int x1=xx[i%points], y1=yy[i%points];
00598      int x2=xx[(i+1)%points], y2=yy[(i+1)%points];
00599      int _res1=(xin-x1)*(y2-y1)-(yin-y1)*(x2-x1);
00600      int _res2=(xfar-x1)*(y2-y1)-(yin-y1)*(x2-x1);
00601      if (!_res1 || !_res2)
00602      {
00603         // The point is on this boundary
00604         return true;
00605      }
00606      if (sign(_res1)*sign(_res2)<0) intersections++;
00607       }
00608    }
00609    return (intersections % 2)!=0;
00610 }
00611 
00612 int
00613 GMapPoly::gma_get_xmin(void) const
00614 {
00615    int x=xx[0];
00616    for(int i=1;i<points;i++)
00617       if (x>xx[i]) x=xx[i];
00618    return x;
00619 }
00620 
00621 int
00622 GMapPoly::gma_get_xmax(void) const
00623 {
00624    int x=xx[0];
00625    for(int i=1;i<points;i++)
00626       if (x<xx[i]) x=xx[i];
00627    return x+1;
00628 }
00629 
00630 int
00631 GMapPoly::gma_get_ymin(void) const
00632 {
00633    int y=yy[0];
00634    for(int i=1;i<points;i++)
00635       if (y>yy[i]) y=yy[i];
00636    return y;
00637 }
00638 
00639 int
00640 GMapPoly::gma_get_ymax(void) const
00641 {
00642    int y=yy[0];
00643    for(int i=1;i<points;i++)
00644       if (y<yy[i]) y=yy[i];
00645    return y+1;
00646 }
00647 
00648 void
00649 GMapPoly::gma_move(int dx, int dy)
00650 {
00651    for(int i=0;i<points;i++)
00652    {
00653       xx[i]+=dx; yy[i]+=dy;
00654    }
00655 }
00656 
00657 void
00658 GMapPoly::gma_resize(int new_width, int new_height)
00659 {
00660    int width=get_xmax()-get_xmin();
00661    int height=get_ymax()-get_ymin();
00662    int xmin=get_xmin(), ymin=get_ymin();
00663    for(int i=0;i<points;i++)
00664    {
00665       xx[i]=xmin+(xx[i]-xmin)*new_width/width;
00666       yy[i]=ymin+(yy[i]-ymin)*new_height/height;
00667    }
00668 }
00669 
00670 void
00671 GMapPoly::gma_transform(const GRect & grect)
00672 {
00673    int width=get_xmax()-get_xmin();
00674    int height=get_ymax()-get_ymin();
00675    int xmin=get_xmin(), ymin=get_ymin();
00676    for(int i=0;i<points;i++)
00677    {
00678       xx[i]=grect.xmin+(xx[i]-xmin)*grect.width()/width;
00679       yy[i]=grect.ymin+(yy[i]-ymin)*grect.height()/height;
00680    }
00681 }
00682 
00683 char const * const
00684 GMapPoly::gma_check_object(void) const
00685 {
00686    const char * str;
00687    str=(border_type!=NO_BORDER &&
00688         border_type!=SOLID_BORDER &&
00689         border_type!=XOR_BORDER) ? error_poly_border:
00690        ((hilite_color!=0xffffffff) ? error_poly_hilite:"");
00691    return str;
00692 }
00693 
00694 GMapPoly::GMapPoly(const int * _xx, const int * _yy, int _points, bool _open) :
00695    open(_open), points(_points)
00696 {
00697    sides=points-(open!=0);
00698    
00699    xx.resize(points-1); yy.resize(points-1);
00700    for(int i=0;i<points;i++)
00701    {
00702       xx[i]=_xx[i]; yy[i]=_yy[i];
00703    }
00704    optimize_data();
00705    char const * const res=check_data();
00706    if (res[0])
00707      G_THROW(res);
00708 }
00709 
00710 int      
00711 GMapPoly::add_vertex(int x, int y)
00712 {
00713     points++;
00714     sides=points-(open!=0);
00715 
00716     xx.resize(points-1); yy.resize(points-1);
00717     xx[points-1] = x;
00718     yy[points-1] = y;
00719 
00720     return points;
00721 }
00722 
00723 void
00724 GMapPoly::close_poly()
00725 {
00726     open = false;
00727     sides=points;
00728 }
00729 
00730 GUTF8String
00731 GMapPoly::gma_print(void)
00732 {
00733    static const GUTF8String space(' ');
00734    GUTF8String res=GUTF8String('(')+POLY_TAG+space;
00735    for(int i=0;i<points;i++)
00736    {
00737       GUTF8String buffer;
00738       res+=buffer.format("%d %d ", xx[i], yy[i]);
00739    }
00740    res.setat(res.length()-1, ')');
00741    res+=space;
00742    return res;
00743 }
00744 
00746 void GMapPoly::get_coords( GList<int> & CoordList ) const
00747 {
00748   for(int i = 0 ; i < points ; i++)
00749   {
00750     CoordList.append( xx[i] );
00751     CoordList.append( yy[i] );
00752   }
00753 }
00754 
00755 void 
00756 GMapPoly::map(GRectMapper &mapper)
00757 {
00758     get_bound_rect();
00759     for(int i=0; i<points; i++)
00760     {
00761         mapper.map(xx[i], yy[i]);
00762     }
00763     clear_bounds();
00764 }
00765 
00766 void 
00767 GMapPoly::unmap(GRectMapper &mapper)
00768 {
00769     get_bound_rect();
00770     for(int i=0; i<points; i++)
00771     {
00772         mapper.unmap(xx[i], yy[i]);
00773     }
00774     clear_bounds();
00775 }
00776 
00777 
00778 
00779 /****************************************************************************
00780 **************************** GMapOval definition ****************************
00781 ****************************************************************************/
00782 
00783 void
00784 GMapOval::gma_resize(int new_width, int new_height)
00785 {
00786    xmax=xmin+new_width;
00787    ymax=ymin+new_height;
00788    initialize();
00789 }
00790 
00791 void
00792 GMapOval::gma_transform(const GRect & grect)
00793 {
00794    xmin=grect.xmin; ymin=grect.ymin;
00795    xmax=grect.xmax; ymax=grect.ymax;
00796    initialize();
00797 }
00798 
00799 bool
00800 GMapOval::gma_is_point_inside(const int x, const int y) const
00801 {
00802    return
00803       sqrt((double)((x-xf1)*(x-xf1)+(y-yf1)*(y-yf1))) +
00804       sqrt((double)((x-xf2)*(x-xf2)+(y-yf2)*(y-yf2))) <= 2*rmax;
00805 }
00806 
00807 char const * const
00808 GMapOval::gma_check_object(void) const
00809 {
00810    return (border_type!=NO_BORDER &&
00811        border_type!=SOLID_BORDER &&
00812        border_type!=XOR_BORDER)?error_oval_border:
00813       ((hilite_color!=0xffffffff) ? error_oval_hilite:"");
00814 }
00815 
00816 void
00817 GMapOval::initialize(void)
00818 {
00819    int xc=(xmax+xmin)/2;
00820    int yc=(ymax+ymin)/2;
00821    int f;
00822    
00823    a=(xmax-xmin)/2;
00824    b=(ymax-ymin)/2;
00825    if (a>b)
00826    {
00827       rmin=b; rmax=a;
00828       f=(int) sqrt((double)(rmax*rmax-rmin*rmin));
00829       xf1=xc+f; xf2=xc-f; yf1=yf2=yc;
00830    } else
00831    {
00832       rmin=a; rmax=b;
00833       f=(int) sqrt((double)(rmax*rmax-rmin*rmin));
00834       yf1=yc+f; yf2=yc-f; xf1=xf2=xc;
00835    }
00836 }
00837 
00838 GMapOval::GMapOval(const GRect & rect) : xmin(rect.xmin), ymin(rect.ymin),
00839    xmax(rect.xmax), ymax(rect.ymax)
00840 {
00841    initialize();
00842 }
00843 
00844 GUTF8String
00845 GMapOval::gma_print(void)
00846 {
00847    GUTF8String buffer;
00848    return buffer.format("(%s %d %d %d %d) ",
00849        OVAL_TAG, xmin, ymin, xmax-xmin, ymax-ymin);
00850 }
00851 
00852 void 
00853 GMapOval::map(GRectMapper &mapper)
00854 {
00855     get_bound_rect();
00856     GRect rect;
00857     rect.xmin = xmin;
00858     rect.xmax = xmax;
00859     rect.ymin = ymin;
00860     rect.ymax = ymax;
00861     mapper.map(rect);
00862     xmin = rect.xmin;
00863     ymin = rect.ymin;
00864     xmax = rect.xmax;
00865     ymax = rect.ymax;
00866     clear_bounds();
00867     initialize();
00868 }
00869 
00870 void 
00871 GMapOval::unmap(GRectMapper &mapper)
00872 {
00873     get_bound_rect();
00874     GRect rect;
00875     rect.xmin = xmin;
00876     rect.xmax = xmax;
00877     rect.ymin = ymin;
00878     rect.ymax = ymax;
00879     mapper.unmap(rect);
00880     xmin = rect.xmin;
00881     ymin = rect.ymin;
00882     xmax = rect.xmax;
00883     ymax = rect.ymax;
00884     clear_bounds();
00885     initialize();
00886 }
00887 
00888 GMapArea::GMapArea(void) : target("_self"), border_type(NO_BORDER),
00889    border_always_visible(false), border_color(0xff), border_width(1),
00890    hilite_color(0xffffffff), bounds_initialized(0) {}
00891 
00892 GMapRect::GMapRect(void) : xmin(0), ymin(0), xmax(0), ymax(0) {}
00893 
00894 GMapRect::GMapRect(const GRect & rect) : xmin(rect.xmin), ymin(rect.ymin),
00895    xmax(rect.xmax), ymax(rect.ymax) {}
00896 
00897 GMapRect &
00898 GMapRect::operator=(const GRect & rect)
00899 {
00900    xmin=rect.xmin;
00901    xmax=rect.xmax;
00902    ymin=rect.ymin;
00903    ymax=rect.ymax;
00904    return *this;
00905 }
00906 
00907 void
00908 GMapRect::gma_move(int dx, int dy)
00909 {
00910    xmin+=dx;
00911    xmax+=dx;
00912    ymin+=dy;
00913    ymax+=dy;
00914 }
00915 
00916 bool
00917 GMapRect::gma_is_point_inside(const int x, const int y) const
00918 {
00919    return (x>=xmin)&&(x<xmax)&&(y>=ymin)&&(y<ymax);
00920 }
00921 
00922 GP<GMapArea>
00923 GMapRect::get_copy(void) const { return new GMapRect(*this); }
00924 
00925 GMapPoly::GMapPoly(void) : points(0), sides(0) {}
00926 
00927 void
00928 GMapPoly::move_vertex(int i, int x, int y)
00929 {
00930    xx[i]=x; yy[i]=y;
00931    clear_bounds();
00932 }
00933 
00934 GP<GMapArea>
00935 GMapPoly::get_copy(void) const { return new GMapPoly(*this); }
00936 
00937 GMapOval::GMapOval(void) : xmin(0), ymin(0), xmax(0), ymax(0) {}
00938 
00939 void
00940 GMapOval::gma_move(int dx, int dy)
00941 {
00942    xmin+=dx; xmax+=dx; ymin+=dy; ymax+=dy;
00943    xf1+=dx; yf1+=dy; xf2+=dx; yf2+=dy;
00944 }
00945 
00946 GP<GMapArea>
00947 GMapOval::get_copy(void) const
00948 {
00949   return new GMapOval(*this);
00950 }
00951 
00952 static GUTF8String
00953 GMapArea2xmltag(const GMapArea &area,const GUTF8String &coords)
00954 {
00955   GUTF8String retval("<AREA coords=\""
00956     +coords+"\" shape=\""+area.get_shape_name()+"\" "
00957     +"alt=\""+area.comment.toEscaped()+"\" ");
00958   if(area.url.length())
00959   {
00960     retval+="href=\""+area.url+"\" ";
00961   }else
00962   {
00963     retval+="nohref=\"nohref\" ";
00964   }
00965   if(area.target.length())
00966   {
00967     retval+="target=\""+area.target.toEscaped()+"\" ";
00968   }
00969   //  highlight
00970   if( area.hilite_color != GMapArea::NO_HILITE &&
00971       area.hilite_color != GMapArea::XOR_HILITE )
00972   {
00973     retval+=GUTF8String().format( "highlight=\"#%06X\" ", area.hilite_color );
00974   }
00975   const char *b_type="none";
00976   switch( area.border_type )
00977   {
00978   case GMapArea::NO_BORDER:
00979     b_type = "none";
00980     break;
00981   case GMapArea::XOR_BORDER:
00982     b_type = "xor";
00983     break;
00984   case GMapArea::SOLID_BORDER:
00985     b_type = "solid";
00986     break;
00987   case GMapArea::SHADOW_IN_BORDER:
00988     b_type = "shadowin";
00989     break;
00990   case GMapArea::SHADOW_OUT_BORDER:
00991     b_type = "shadowout";
00992     break;
00993   case GMapArea::SHADOW_EIN_BORDER:
00994     b_type = "etchedin";
00995     break;
00996   case GMapArea::SHADOW_EOUT_BORDER:
00997     b_type = "etchedout";
00998     break;
00999   }
01000   retval=retval+"bordertype=\""+b_type+"\" ";
01001   if( area.border_type != GMapArea::NO_BORDER)
01002   {
01003     retval+="bordercolor=\""+GUTF8String().format("#%06X",area.border_color)
01004       +"\" border=\""+GUTF8String(area.border_width)+"\" ";
01005   }
01006   if(area.border_always_visible )
01007     retval=retval+"visible=\"visible\" ";
01008   return retval+"/>\n";
01009 }
01010 
01011 GUTF8String
01012 GMapRect::get_xmltag(const int height) const
01013 {
01014   return GMapArea2xmltag( *this, GUTF8String(get_xmin())
01015     +","+GUTF8String(height-1-get_ymax())
01016     +","+GUTF8String(get_xmax())
01017     +","+GUTF8String(height-1-get_ymin()));
01018 #if 0
01019   GUTF8String retval;
01020   return retval;
01021 #endif
01022 }
01023 
01024 GUTF8String
01025 GMapOval::get_xmltag(const int height) const
01026 { 
01027   return GMapArea2xmltag( *this, GUTF8String(get_xmin())
01028     +","+GUTF8String(height-1-get_ymax())
01029     +","+GUTF8String(get_xmax())
01030     +","+GUTF8String(height-1-get_ymin()));
01031 #if 0
01032   GUTF8String retval;
01033   return retval;
01034 #endif
01035 }
01036 
01037 GUTF8String
01038 GMapPoly::get_xmltag(const int height) const
01039 {
01040   GList<int> CoordList;
01041   get_coords(CoordList);
01042   GPosition pos=CoordList;
01043   GUTF8String retval;
01044   if(pos)
01045   {
01046     GUTF8String coords(CoordList[pos]);
01047     while(++pos)
01048     {
01049       coords+=","+GUTF8String(height-1-CoordList[pos]);
01050       if(! ++pos)
01051         break;
01052       coords+=","+GUTF8String(CoordList[pos]);
01053     }
01054     retval=GMapArea2xmltag( *this, coords);
01055   }
01056   return retval;
01057 }
01058 
01059 
01060 #ifdef HAVE_NAMESPACES
01061 }
01062 # ifndef NOT_USING_DJVU_NAMESPACE
01063 using namespace DJVU;
01064 # endif
01065 #endif
01066 

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