changeset 1238:988e79f0f398

fix image map coordinates when margin/border/padding are present
author corvid <corvid@lavabit.com>
date Mon, 20 Jul 2009 21:57:47 +0000
parents 688f9ad32e2a
children 0ef301d99822
files ChangeLog dw/image.cc dw/image.hh
diffstat 3 files changed, 52 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Sun Jul 19 03:17:11 2009 +0000
+++ b/ChangeLog	Mon Jul 20 21:57:47 2009 +0000
@@ -14,7 +14,8 @@
  - Added a_Dpip_get_attr_l() to DPIP's API.
    Patches: Jorge Arellano Cid
 +- Fix segfault from AREA when MAP is missing name attribute.
-   Patch: corvid
+ - Fix image map coordinates when margin/border/padding present.
+   Patches: corvid
 
 -----------------------------------------------------------------------------
 
--- a/dw/image.cc	Sun Jul 19 03:17:11 2009 +0000
+++ b/dw/image.cc	Mon Jul 20 21:57:47 2009 +0000
@@ -242,21 +242,47 @@
    }
 }
 
+/*
+ * Return the coordinate relative to the contents.
+ * If the event occurred in the surrounding box, return the value at the
+ * edge of the contents instead.
+ */
+int Image::contentX (core::MousePositionEvent *event)
+{
+   int ret = event->xWidget - getStyle()->boxOffsetX();
+
+   ret = misc::min(getContentWidth(), misc::max(ret, 0));
+   return ret;
+}
+
+int Image::contentY (core::MousePositionEvent *event)
+{
+   int ret = event->yWidget - getStyle()->boxOffsetY();
+
+   ret = misc::min(getContentHeight(), misc::max(ret, 0));
+   return ret;
+}
+
 bool Image::motionNotifyImpl (core::EventMotion *event)
 {
-   if (mapList) {
-      /* client-side image map */
-      int newLink = mapList->link (mapKey, event->xWidget, event->yWidget);
-      if (newLink != currLink) {
-         currLink = newLink;
-         clicking = false;
-         setCursor(newLink == -1 ? core::style::CURSOR_DEFAULT :
-                                   core::style::CURSOR_POINTER);
-         (void) emitLinkEnter (newLink, -1, -1, -1);
+   if (mapList || isMap) {
+      int x = contentX(event);
+      int y = contentY(event);
+
+      if (mapList) {
+         /* client-side image map */
+         int newLink = mapList->link (mapKey, x, y);
+         if (newLink != currLink) {
+            currLink = newLink;
+            clicking = false;
+            setCursor(newLink == -1 ? core::style::CURSOR_DEFAULT :
+                                      core::style::CURSOR_POINTER);
+            (void) emitLinkEnter (newLink, -1, -1, -1);
+         }
+      } else if (isMap && currLink != -1) {
+         /* server-side image map */
+         (void) emitLinkEnter (currLink, -1, x, y);
       }
-   } else if (isMap && currLink != -1) {
-      /* server-side image map */
-      (void) emitLinkEnter (currLink, -1, event->xWidget, event->yWidget);
    }
    return true;
 }
@@ -264,8 +290,9 @@
 bool Image::buttonPressImpl (core::EventButton *event)
 {
    bool ret = false;
-   currLink = mapList ? mapList->link (mapKey, event->xWidget, event->yWidget):
-      getStyle()->x_link;
+
+   currLink = mapList? mapList->link (mapKey, contentX(event),contentY(event)):
+              getStyle()->x_link;
    if (event->button == 3){
       (void)emitLinkPress(currLink, getStyle()->x_img, -1,-1,event);
       ret = true;
@@ -278,11 +305,14 @@
 
 bool Image::buttonReleaseImpl (core::EventButton *event)
 {
-   currLink = mapList ? mapList->link (mapKey, event->xWidget, event->yWidget):
-      getStyle()->x_link;
+   int x = -1, y = -1;
+
+   if (mapList || isMap) {
+      x = contentX(event);
+      y = contentY(event);
+   }
+   currLink = mapList ? mapList->link (mapKey, x, y) : getStyle()->x_link;
    if (clicking) {
-      int x = isMap ? event->xWidget : -1;
-      int y = isMap ? event->yWidget : -1;
       clicking = false;
       emitLinkClick (currLink, getStyle()->x_img, x, y, event);
       return true;
--- a/dw/image.hh	Sun Jul 19 03:17:11 2009 +0000
+++ b/dw/image.hh	Mon Jul 20 21:57:47 2009 +0000
@@ -136,6 +136,8 @@
    void enterNotifyImpl (core::EventCrossing *event);
    void leaveNotifyImpl (core::EventCrossing *event);
    bool motionNotifyImpl (core::EventMotion *event);
+   int contentX (core::MousePositionEvent *event);
+   int contentY (core::MousePositionEvent *event);
 
    //core::Iterator *iterator (Content::Type mask, bool atEnd);