home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / src / html / m_image.cpp < prev    next >
C/C++ Source or Header  |  2002-11-09  |  23KB  |  728 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        m_image.cpp
  3. // Purpose:     wxHtml module for displaying images
  4. // Author:      Vaclav Slavik
  5. // RCS-ID:      $Id: m_image.cpp,v 1.37.2.3 2002/11/09 00:07:32 VS Exp $
  6. // Copyright:   (c) 1999 Vaclav Slavik, Joel Lucsy
  7. // Licence:     wxWindows Licence
  8. /////////////////////////////////////////////////////////////////////////////
  9.  
  10. #ifdef __GNUG__
  11. #pragma implementation
  12. #endif
  13.  
  14. #include "wx/wxprec.h"
  15.  
  16. #include "wx/defs.h"
  17. #if wxUSE_HTML && wxUSE_STREAMS
  18.  
  19. #ifdef __BORLANDC__
  20. #pragma hdrstop
  21. #endif
  22.  
  23. #ifndef WXPRECOMP
  24.     #include "wx/dc.h"
  25.     #include "wx/scrolwin.h"
  26.     #include "wx/timer.h"
  27.     #include "wx/dcmemory.h"
  28. #endif
  29.  
  30. #include "wx/html/forcelnk.h"
  31. #include "wx/html/m_templ.h"
  32. #include "wx/html/htmlwin.h"
  33.  
  34. #include "wx/image.h"
  35. #include "wx/gifdecod.h"
  36. #include "wx/dynarray.h"
  37. #include "wx/log.h"
  38.  
  39. #include <math.h>
  40. #include <float.h>
  41.  
  42. FORCE_LINK_ME(m_image)
  43.  
  44.  
  45.  
  46.  
  47. WX_DECLARE_OBJARRAY(int, CoordArray);
  48. #include "wx/arrimpl.cpp" // this is a magic incantation which must be done!
  49. WX_DEFINE_OBJARRAY(CoordArray);
  50.  
  51.  
  52. //--------------------------------------------------------------------------------
  53. // wxHtmlImageMapAreaCell
  54. //                  0-width, 0-height cell that represents single area in imagemap
  55. //                  (it's GetLink is called from wxHtmlImageCell's)
  56. //--------------------------------------------------------------------------------
  57.  
  58. class wxHtmlImageMapAreaCell : public wxHtmlCell
  59. {
  60.     public:
  61.         enum celltype { CIRCLE, RECT, POLY };
  62.     protected:
  63.         CoordArray coords;
  64.         celltype type;
  65.         int radius;
  66.     public:
  67.         wxHtmlImageMapAreaCell( celltype t, wxString &coords, double pixel_scale = 1.0);
  68.         virtual wxHtmlLinkInfo *GetLink( int x = 0, int y = 0 ) const;
  69. };
  70.  
  71.  
  72.  
  73.  
  74.  
  75. wxHtmlImageMapAreaCell::wxHtmlImageMapAreaCell( wxHtmlImageMapAreaCell::celltype t, wxString &incoords, double pixel_scale )
  76. {
  77.     int i;
  78.     wxString x = incoords, y;
  79.  
  80.     type = t;
  81.     while ((i = x.Find( ',' )) != -1)
  82.     {
  83.         coords.Add( (int)(pixel_scale * (double)wxAtoi( x.Left( i ).c_str())) );
  84.         x = x.Mid( i + 1 );
  85.     }
  86.     coords.Add( (int)(pixel_scale * (double)wxAtoi( x.c_str())) );
  87. }
  88.  
  89. wxHtmlLinkInfo *wxHtmlImageMapAreaCell::GetLink( int x, int y ) const
  90. {
  91.     switch (type)
  92.     {
  93.         case RECT:
  94.             {
  95.                 int l, t, r, b;
  96.  
  97.                 l = coords[ 0 ];
  98.                 t = coords[ 1 ];
  99.                 r = coords[ 2 ];
  100.                 b = coords[ 3 ];
  101.                 if (x >= l && x <= r && y >= t && y <= b)
  102.                 {
  103.                     return m_Link;
  104.                 }
  105.                 break;
  106.             }
  107.         case CIRCLE:
  108.             {
  109.                 int l, t, r;
  110.                 double  d;
  111.  
  112.                 l = coords[ 0 ];
  113.                 t = coords[ 1 ];
  114.                 r = coords[ 2 ];
  115.                 d = sqrt( (double) (((x - l) * (x - l)) + ((y - t) * (y - t))) );
  116.                 if (d < (double)r)
  117.                 {
  118.                     return m_Link;
  119.                 }
  120.             }
  121.             break;
  122.         case POLY:
  123.             {
  124.                 if (coords.GetCount() >= 6)
  125.                 {
  126.                     int intersects = 0;
  127.                     int wherex = x;
  128.                     int wherey = y;
  129.                     int totalv = coords.GetCount() / 2;
  130.                     int totalc = totalv * 2;
  131.                     int xval = coords[totalc - 2];
  132.                     int yval = coords[totalc - 1];
  133.                     int end = totalc;
  134.                     int pointer = 1;
  135.  
  136.                     if ((yval >= wherey) != (coords[pointer] >= wherey))
  137.                     {
  138.                         if ((xval >= wherex) == (coords[0] >= wherex))
  139.                         {
  140.                             intersects += (xval >= wherex) ? 1 : 0;
  141.                         }
  142.                         else
  143.                         {
  144.                             intersects += ((xval - (yval - wherey) *
  145.                                             (coords[0] - xval) /
  146.                                             (coords[pointer] - yval)) >= wherex) ? 1 : 0;
  147.                         }
  148.                     }
  149.  
  150.                     while (pointer < end)
  151.                     {
  152.                         yval = coords[pointer];
  153.                         pointer += 2;
  154.                         if (yval >= wherey)
  155.                         {
  156.                             while ((pointer < end) && (coords[pointer] >= wherey))
  157.                             {
  158.                                 pointer += 2;
  159.                             }
  160.                             if (pointer >= end)
  161.                             {
  162.                                 break;
  163.                             }
  164.                             if ((coords[pointer - 3] >= wherex) ==
  165.                                     (coords[pointer - 1] >= wherex)) {
  166.                                 intersects += (coords[pointer - 3] >= wherex) ? 1 : 0;
  167.                             }
  168.                             else
  169.                             {
  170.                                 intersects +=
  171.                                     ((coords[pointer - 3] - (coords[pointer - 2] - wherey) *
  172.                                       (coords[pointer - 1] - coords[pointer - 3]) /
  173.                                       (coords[pointer] - coords[pointer - 2])) >= wherex) ? 1 : 0;
  174.                             }
  175.                         }
  176.                         else
  177.                         {
  178.                             while ((pointer < end) && (coords[pointer] < wherey))
  179.                             {
  180.                                 pointer += 2;
  181.                             }
  182.                             if (pointer >= end)
  183.                             {
  184.                                 break;
  185.                             }
  186.                             if ((coords[pointer - 3] >= wherex) ==
  187.                                     (coords[pointer - 1] >= wherex))
  188.                             {
  189.                                 intersects += (coords[pointer - 3] >= wherex) ? 1 : 0;
  190.                             }
  191.                             else
  192.                             {
  193.                                 intersects +=
  194.                                     ((coords[pointer - 3] - (coords[pointer - 2] - wherey) *
  195.                                       (coords[pointer - 1] - coords[pointer - 3]) /
  196.                                       (coords[pointer] - coords[pointer - 2])) >= wherex) ? 1 : 0;
  197.                             }
  198.                         }
  199.                     }
  200.                     if ((intersects & 1) != 0)
  201.                     {
  202.                         return m_Link;
  203.                     }
  204.                 }
  205.             }
  206.             break;
  207.     }
  208.  
  209.     if (m_Next)
  210.     {
  211.         wxHtmlImageMapAreaCell  *a = (wxHtmlImageMapAreaCell*)m_Next;
  212.         return a->GetLink( x, y );
  213.     }
  214.     return NULL;
  215. }
  216.  
  217.  
  218.  
  219.  
  220.  
  221.  
  222.  
  223.  
  224. //--------------------------------------------------------------------------------
  225. // wxHtmlImageMapCell
  226. //                  0-width, 0-height cell that represents map from imagemaps
  227. //                  it is always placed before wxHtmlImageMapAreaCells
  228. //                  It responds to Find(wxHTML_COND_ISIMAGEMAP)
  229. //--------------------------------------------------------------------------------
  230.  
  231.  
  232. class wxHtmlImageMapCell : public wxHtmlCell
  233. {
  234.     public:
  235.         wxHtmlImageMapCell( wxString &name );
  236.     protected:
  237.         wxString m_Name;
  238.     public:
  239.         virtual wxHtmlLinkInfo *GetLink( int x = 0, int y = 0 ) const;
  240.         virtual const wxHtmlCell *Find( int cond, const void *param ) const;
  241. };
  242.  
  243.  
  244. wxHtmlImageMapCell::wxHtmlImageMapCell( wxString &name )
  245. {
  246.     m_Name = name ;
  247. }
  248.  
  249. wxHtmlLinkInfo *wxHtmlImageMapCell::GetLink( int x, int y ) const
  250. {
  251.     wxHtmlImageMapAreaCell  *a = (wxHtmlImageMapAreaCell*)m_Next;
  252.     if (a)
  253.         return a->GetLink( x, y );
  254.     return wxHtmlCell::GetLink( x, y );
  255. }
  256.  
  257. const wxHtmlCell *wxHtmlImageMapCell::Find( int cond, const void *param ) const
  258. {
  259.     if (cond == wxHTML_COND_ISIMAGEMAP)
  260.     {
  261.         if (m_Name == *((wxString*)(param)))
  262.             return this;
  263.     }
  264.     return wxHtmlCell::Find(cond, param);
  265. }
  266.  
  267.  
  268.  
  269.  
  270.  
  271. //--------------------------------------------------------------------------------
  272. // wxHtmlImageCell
  273. //                  Image/bitmap
  274. //--------------------------------------------------------------------------------
  275.  
  276. class wxHtmlImageCell : public wxHtmlCell
  277. {
  278. public:
  279.     wxHtmlImageCell(wxWindow *window,
  280.                     wxFSFile *input, int w = -1, int h = -1,
  281.                     double scale = 1.0, int align = wxHTML_ALIGN_BOTTOM,
  282.                     const wxString& mapname = wxEmptyString);
  283.     ~wxHtmlImageCell();
  284.     void Draw(wxDC& dc, int x, int y, int view_y1, int view_y2);
  285.     virtual wxHtmlLinkInfo *GetLink(int x = 0, int y = 0) const;
  286.  
  287.     void SetImage(const wxImage& img);
  288. #if wxUSE_GIF && wxUSE_TIMER
  289.     void AdvanceAnimation(wxTimer *timer);
  290.     virtual void Layout(int w);
  291. #endif
  292.  
  293. private:
  294.     wxBitmap           *m_bitmap;
  295.     int                 m_bmpW, m_bmpH;
  296.     bool                m_showFrame:1;
  297.     wxScrolledWindow   *m_window;
  298. #if wxUSE_GIF && wxUSE_TIMER
  299.     wxGIFDecoder       *m_gifDecoder;
  300.     wxTimer            *m_gifTimer;
  301.     int                 m_physX, m_physY;
  302. #endif
  303.     double              m_scale;
  304.     wxHtmlImageMapCell *m_imageMap;
  305.     wxString            m_mapName;
  306. };
  307.  
  308. #if wxUSE_GIF && wxUSE_TIMER
  309. class wxGIFTimer : public wxTimer
  310. {
  311.     public:
  312.         wxGIFTimer(wxHtmlImageCell *cell) : m_cell(cell) {}
  313.         virtual void Notify()
  314.         {
  315.             m_cell->AdvanceAnimation(this);
  316.         }
  317.  
  318.     private:
  319.         wxHtmlImageCell *m_cell;
  320. };
  321. #endif
  322.  
  323.  
  324. //--------------------------------------------------------------------------------
  325. // wxHtmlImageCell
  326. //--------------------------------------------------------------------------------
  327.  
  328. /* XPM */
  329. static const char * broken_image_xpm[] = {
  330. "29 31 7 1",
  331. "   c None",
  332. ".  c #808080",
  333. "+  c #FFFFFF",
  334. "@  c #C0C0C0",
  335. "#  c #000000",
  336. "$  c #333366",
  337. "%  c #B2B2B2",
  338. ".....................        ",
  339. ".+++++++++++++++++++..       ",
  340. ".+++++++++++++++++++.@.      ",
  341. ".++@@@@@@@@@@@@@@@@@.+@.     ",
  342. ".++@@@@@@@@@@@@@@@@@.++@.    ",
  343. ".++@@@@@.@@@@.@@@@@@.+++@.   ",
  344. ".++@@@@@@@@@@@@@@@@@.++++@.  ",
  345. ".++@@@@@@@@@@@@@@@@@.+++++@. ",
  346. ".++@@.@@@@@@@@@@.@@@######## ",
  347. ".++@@@@@@@@@@@@@@@@@@$$$$$$#.",
  348. ".######@@@@@@@@@@@@@@@.....#.",
  349. "       ###@@@@@@@@@@@@@@@++#.",
  350. "          #####@@@@@@@@@@++#.",
  351. "              #@.@@@@@@@@++#.",
  352. "..             ###@@@@@@@++#.",
  353. ".+....            #@@@@@@++#.",
  354. ".++@@@...          ####@@++#.",
  355. ".++@@@@@@..            #####.",
  356. ".++@@@@@@@@...               ",
  357. ".++@@@@@@%%%%@.              ",
  358. ".++@@@@@@%%%%@@....          ",
  359. ".++@@@@@@%%%%@@@@@@....      ",
  360. ".++@@@@@@%%%%@@@@@@@@@@....  ",
  361. ".++@@@@@@@@@@@@@@@@@@@@@@++#.",
  362. ".++@@@@@@@@@@@@@@@@@@@@@@++#.",
  363. ".++@@@@@@@@@@@@@@@@@@@@@@++#.",
  364. ".++@@@@@@@@@@@@@@@@@@@@@@++#.",
  365. ".++@@@@@@@@@@@@@@@@@@@@@@++#.",
  366. ".++++++++++++++++++++++++++#.",
  367. ".++++++++++++++++++++++++++#.",
  368. "############################."};
  369.  
  370. wxHtmlImageCell::wxHtmlImageCell(wxWindow *window, wxFSFile *input,
  371.                                  int w, int h, double scale, int align,
  372.                                  const wxString& mapname) : wxHtmlCell()
  373. {
  374.     m_window = window ? wxStaticCast(window, wxScrolledWindow) : NULL;
  375.     m_scale = scale;
  376.     m_showFrame = FALSE;
  377.     m_bitmap = NULL;
  378.     m_bmpW = w;
  379.     m_bmpH = h;
  380.     m_imageMap = NULL;
  381.     m_mapName = mapname;
  382.     SetCanLiveOnPagebreak(FALSE);
  383. #if wxUSE_GIF && wxUSE_TIMER
  384.     m_gifDecoder = NULL;
  385.     m_gifTimer = NULL;
  386.     m_physX = m_physY = -1;
  387. #endif
  388.  
  389.     if ( m_bmpW && m_bmpH )
  390.     {
  391.         if ( input )
  392.         {
  393.             wxInputStream *s = input->GetStream();
  394.  
  395.             if ( s )
  396.             {
  397.                 bool readImg = TRUE;
  398.  
  399. #if wxUSE_GIF && wxUSE_TIMER
  400.                 if ( (input->GetLocation().Matches(wxT("*.gif")) ||
  401.                       input->GetLocation().Matches(wxT("*.GIF"))) && m_window )
  402.                 {
  403.                     m_gifDecoder = new wxGIFDecoder(s, TRUE);
  404.                     if ( m_gifDecoder->ReadGIF() == wxGIF_OK )
  405.                     {
  406.                         wxImage img;
  407.                         if ( m_gifDecoder->ConvertToImage(&img) )
  408.                             SetImage(img);
  409.  
  410.                         readImg = FALSE;
  411.  
  412.                         if ( m_gifDecoder->IsAnimation() )
  413.                         {
  414.                             m_gifTimer = new wxGIFTimer(this);
  415.                             m_gifTimer->Start(m_gifDecoder->GetDelay(), TRUE);
  416.                         }
  417.                         else
  418.                         {
  419.                             wxDELETE(m_gifDecoder);
  420.                         }
  421.                     }
  422.                     else
  423.                     {
  424.                         wxDELETE(m_gifDecoder);
  425.                     }
  426.                 }
  427.  
  428.                 if ( readImg )
  429. #endif // wxUSE_GIF && wxUSE_TIMER
  430.                 {
  431.                     wxImage image(*s, wxBITMAP_TYPE_ANY);
  432.                     if ( image.Ok() )
  433.                         SetImage(image);
  434.                 }
  435.             }
  436.         }
  437.         else // input==NULL, use "broken image" bitmap
  438.         {
  439.             if ( m_bmpW == -1 && m_bmpH == -1 )
  440.             {
  441.                 m_bmpW = 29;
  442.                 m_bmpH = 31;
  443.             }
  444.             else
  445.             {
  446.                 m_showFrame = TRUE;
  447.                 if ( m_bmpW == -1 ) m_bmpW = 31;
  448.                 if ( m_bmpH == -1 ) m_bmpH = 33;
  449.             }
  450.             m_bitmap = new wxBitmap(broken_image_xpm);
  451.         }
  452.     }
  453.     //else: ignore the 0-sized images used sometimes on the Web pages
  454.  
  455.     m_Width = (int)(scale * (double)m_bmpW);
  456.     m_Height = (int)(scale * (double)m_bmpH);
  457.  
  458.     switch (align)
  459.     {
  460.         case wxHTML_ALIGN_TOP :
  461.             m_Descent = m_Height;
  462.             break;
  463.         case wxHTML_ALIGN_CENTER :
  464.             m_Descent = m_Height / 2;
  465.             break;
  466.         case wxHTML_ALIGN_BOTTOM :
  467.         default :
  468.             m_Descent = 0;
  469.             break;
  470.     }
  471.  }
  472.  
  473. void wxHtmlImageCell::SetImage(const wxImage& img)
  474. {
  475.     if ( img.Ok() )
  476.     {
  477.         delete m_bitmap;
  478.  
  479.         int ww, hh;
  480.         ww = img.GetWidth();
  481.         hh = img.GetHeight();
  482.  
  483.         if ( m_bmpW == -1 )
  484.             m_bmpW = ww;
  485.         if ( m_bmpH == -1 )
  486.             m_bmpH = hh;
  487.  
  488.         if ((m_bmpW != ww) || (m_bmpH != hh))
  489.         {
  490.             wxImage img2 = img.Scale(m_bmpW, m_bmpH);
  491.             m_bitmap = new wxBitmap(img2);
  492.         }
  493.         else
  494.             m_bitmap = new wxBitmap(img);
  495.     }
  496. }
  497.  
  498. #if wxUSE_GIF && wxUSE_TIMER
  499. void wxHtmlImageCell::AdvanceAnimation(wxTimer *timer)
  500. {
  501.     wxImage img;
  502.  
  503.     m_gifDecoder->GoNextFrame(TRUE);
  504.  
  505.     if ( m_physX == -1 )
  506.     {
  507.         m_physX = m_physY = 0;
  508.         for (wxHtmlCell *cell = this; cell; cell = cell->GetParent())
  509.         {
  510.             m_physX += cell->GetPosX();
  511.             m_physY += cell->GetPosY();
  512.         }
  513.     }
  514.  
  515.     int x, y;
  516.     m_window->CalcScrolledPosition(m_physX, m_physY, &x, &y);
  517.     wxRect rect(x, y, m_Width, m_Height);
  518.  
  519.     if ( m_window->GetClientRect().Intersects(rect) &&
  520.          m_gifDecoder->ConvertToImage(&img) )
  521.     {
  522.         if ( (int)m_gifDecoder->GetWidth() != m_Width ||
  523.              (int)m_gifDecoder->GetHeight() != m_Height ||
  524.              m_gifDecoder->GetLeft() != 0 || m_gifDecoder->GetTop() != 0 )
  525.         {
  526.             wxBitmap bmp(img);
  527.             wxMemoryDC dc;
  528.             dc.SelectObject(*m_bitmap);
  529.             dc.DrawBitmap(bmp, m_gifDecoder->GetLeft(), m_gifDecoder->GetTop());
  530.         }
  531.         else
  532.             SetImage(img);
  533.         m_window->Refresh(img.HasMask(), &rect);
  534.     }
  535.  
  536.     timer->Start(m_gifDecoder->GetDelay(), TRUE);
  537. }
  538.  
  539. void wxHtmlImageCell::Layout(int w)
  540. {
  541.     wxHtmlCell::Layout(w);
  542.     m_physX = m_physY = -1;
  543. }
  544.  
  545. #endif
  546.  
  547. wxHtmlImageCell::~wxHtmlImageCell()
  548. {
  549.     delete m_bitmap;
  550. #if wxUSE_GIF && wxUSE_TIMER
  551.     delete m_gifTimer;
  552.     delete m_gifDecoder;
  553. #endif
  554. }
  555.  
  556.  
  557. void wxHtmlImageCell::Draw(wxDC& dc, int x, int y, int WXUNUSED(view_y1), int WXUNUSED(view_y2))
  558. {
  559.     if ( m_showFrame )
  560.     {
  561.         dc.SetBrush(*wxTRANSPARENT_BRUSH);
  562.         dc.SetPen(*wxBLACK_PEN);
  563.         dc.DrawRectangle(x + m_PosX, y + m_PosY, m_Width, m_Height);
  564.         x++, y++;
  565.     }
  566.     if ( m_bitmap )
  567.     {
  568.         double us_x, us_y;
  569.         dc.GetUserScale(&us_x, &us_y);
  570.         dc.SetUserScale(us_x * m_scale, us_y * m_scale);
  571.  
  572.         dc.DrawBitmap(*m_bitmap, (int) ((x + m_PosX) / m_scale),
  573.                                  (int) ((y + m_PosY) / m_scale), TRUE);
  574.         dc.SetUserScale(us_x, us_y);
  575.     }
  576. }
  577.  
  578. wxHtmlLinkInfo *wxHtmlImageCell::GetLink( int x, int y ) const
  579. {
  580.     if (m_mapName.IsEmpty())
  581.         return wxHtmlCell::GetLink( x, y );
  582.     if (!m_imageMap)
  583.     {
  584.         wxHtmlContainerCell *p, *op;
  585.         op = p = GetParent();
  586.         while (p)
  587.         {
  588.             op = p;
  589.             p = p->GetParent();
  590.         }
  591.         p = op;
  592.         wxHtmlCell *cell = (wxHtmlCell*)p->Find(wxHTML_COND_ISIMAGEMAP,
  593.                                                 (const void*)(&m_mapName));
  594.         if (!cell)
  595.         {
  596.             ((wxString&)m_mapName).Clear();
  597.             return wxHtmlCell::GetLink( x, y );
  598.         }
  599.         {   // dirty hack, ask Joel why he fills m_ImageMap in this place
  600.             // THE problem is that we're in const method and we can't modify m_ImageMap
  601.             wxHtmlImageMapCell **cx = (wxHtmlImageMapCell**)(&m_imageMap);
  602.             *cx = (wxHtmlImageMapCell*)cell;
  603.         }
  604.     }
  605.     return m_imageMap->GetLink(x, y);
  606. }
  607.  
  608.  
  609.  
  610. //--------------------------------------------------------------------------------
  611. // tag handler
  612. //--------------------------------------------------------------------------------
  613.  
  614. TAG_HANDLER_BEGIN(IMG, "IMG,MAP,AREA")
  615.  
  616.     TAG_HANDLER_PROC(tag)
  617.     {
  618.         if (tag.GetName() == wxT("IMG"))
  619.         {
  620.             if (tag.HasParam(wxT("SRC")))
  621.             {
  622.                 int w = -1, h = -1;
  623.                 int al;
  624.                 wxFSFile *str;
  625.                 wxString tmp = tag.GetParam(wxT("SRC"));
  626.                 wxString mn = wxEmptyString;
  627.  
  628.                 str = m_WParser->OpenURL(wxHTML_URL_IMAGE, tmp);
  629.  
  630.                 if (tag.HasParam(wxT("WIDTH")))
  631.                     tag.GetParamAsInt(wxT("WIDTH"), &w);
  632.                 if (tag.HasParam(wxT("HEIGHT")))
  633.                     tag.GetParamAsInt(wxT("HEIGHT"), &h);
  634.                 al = wxHTML_ALIGN_BOTTOM;
  635.                 if (tag.HasParam(wxT("ALIGN")))
  636.                 {
  637.                     wxString alstr = tag.GetParam(wxT("ALIGN"));
  638.                     alstr.MakeUpper();  // for the case alignment was in ".."
  639.                     if (alstr == wxT("TEXTTOP"))
  640.                         al = wxHTML_ALIGN_TOP;
  641.                     else if ((alstr == wxT("CENTER")) || (alstr == wxT("ABSCENTER")))
  642.                         al = wxHTML_ALIGN_CENTER;
  643.                 }
  644.                 if (tag.HasParam(wxT("USEMAP")))
  645.                 {
  646.                     mn = tag.GetParam( wxT("USEMAP") );
  647.                     if (mn.GetChar(0) == wxT('#'))
  648.                     {
  649.                         mn = mn.Mid( 1 );
  650.                     }
  651.                 }
  652.                 wxHtmlImageCell *cel = new wxHtmlImageCell(
  653.                                           m_WParser->GetWindow(),
  654.                                           str, w, h,
  655.                                           m_WParser->GetPixelScale(),
  656.                                           al, mn);
  657.                 cel->SetLink(m_WParser->GetLink());
  658.                 cel->SetId(tag.GetParam(wxT("id"))); // may be empty
  659.                 m_WParser->GetContainer()->InsertCell(cel);
  660.                 if (str)
  661.                     delete str;
  662.             }
  663.         }
  664.         if (tag.GetName() == wxT("MAP"))
  665.         {
  666.             m_WParser->CloseContainer();
  667.             m_WParser->OpenContainer();
  668.             if (tag.HasParam(wxT("NAME")))
  669.             {
  670.                 wxString tmp = tag.GetParam(wxT("NAME"));
  671.                 wxHtmlImageMapCell *cel = new wxHtmlImageMapCell( tmp );
  672.                 m_WParser->GetContainer()->InsertCell( cel );
  673.             }
  674.             ParseInner( tag );
  675.             m_WParser->CloseContainer();
  676.             m_WParser->OpenContainer();
  677.         }
  678.         if (tag.GetName() == wxT("AREA"))
  679.         {
  680.             if (tag.HasParam(wxT("SHAPE")))
  681.             {
  682.                 wxString tmp = tag.GetParam(wxT("SHAPE"));
  683.                 wxString coords = wxEmptyString;
  684.                 tmp.MakeUpper();
  685.                 wxHtmlImageMapAreaCell *cel = NULL;
  686.                 if (tag.HasParam(wxT("COORDS")))
  687.                 {
  688.                     coords = tag.GetParam(wxT("COORDS"));
  689.                 }
  690.                 if (tmp == wxT("POLY"))
  691.                 {
  692.                     cel = new wxHtmlImageMapAreaCell( wxHtmlImageMapAreaCell::POLY, coords, m_WParser->GetPixelScale() );
  693.                 }
  694.                 else if (tmp == wxT("CIRCLE"))
  695.                 {
  696.                     cel = new wxHtmlImageMapAreaCell( wxHtmlImageMapAreaCell::CIRCLE, coords, m_WParser->GetPixelScale() );
  697.                 }
  698.                 else if (tmp == wxT("RECT"))
  699.                 {
  700.                     cel = new wxHtmlImageMapAreaCell( wxHtmlImageMapAreaCell::RECT, coords, m_WParser->GetPixelScale() );
  701.                 }
  702.                 if (cel != NULL && tag.HasParam(wxT("HREF")))
  703.                 {
  704.                     wxString tmp = tag.GetParam(wxT("HREF"));
  705.                     wxString target = wxEmptyString;
  706.                     if (tag.HasParam(wxT("TARGET"))) target = tag.GetParam(wxT("TARGET"));
  707.                     cel->SetLink( wxHtmlLinkInfo(tmp, target));
  708.                 }
  709.                 if (cel != NULL) m_WParser->GetContainer()->InsertCell( cel );
  710.             }
  711.         }
  712.  
  713.         return FALSE;
  714.     }
  715.  
  716. TAG_HANDLER_END(IMG)
  717.  
  718.  
  719.  
  720. TAGS_MODULE_BEGIN(Image)
  721.  
  722.     TAGS_MODULE_ADD(IMG)
  723.  
  724. TAGS_MODULE_END(Image)
  725.  
  726.  
  727. #endif
  728.