Vincent Povirk : gdiplus: Detect hotkey prefixes when drawing strings.

Alexandre Julliard julliard at winehq.org
Mon Mar 26 12:29:29 CDT 2012


Module: wine
Branch: master
Commit: eef459968a480cb62c422cecb38f8844644779dd
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=eef459968a480cb62c422cecb38f8844644779dd

Author: Vincent Povirk <vincent at codeweavers.com>
Date:   Wed Mar 21 12:50:11 2012 -0500

gdiplus: Detect hotkey prefixes when drawing strings.

---

 dlls/gdiplus/gdiplus_private.h |    3 +-
 dlls/gdiplus/graphics.c        |   57 +++++++++++++++++++++++++++++++++++++---
 dlls/gdiplus/graphicspath.c    |    6 +++-
 3 files changed, 60 insertions(+), 6 deletions(-)

diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h
index 3cd01b4..24df3dd 100644
--- a/dlls/gdiplus/gdiplus_private.h
+++ b/dlls/gdiplus/gdiplus_private.h
@@ -424,7 +424,8 @@ struct GpRegion{
 typedef GpStatus (*gdip_format_string_callback)(HDC hdc,
     GDIPCONST WCHAR *string, INT index, INT length, GDIPCONST GpFont *font,
     GDIPCONST RectF *rect, GDIPCONST GpStringFormat *format,
-    INT lineno, const RectF *bounds, void *user_data);
+    INT lineno, const RectF *bounds, INT *underlined_indexes,
+    INT underlined_index_count, void *user_data);
 
 GpStatus gdip_format_string(HDC hdc,
     GDIPCONST WCHAR *string, INT length, GDIPCONST GpFont *font,
diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c
index cbaf3ed..c5ac9d1 100644
--- a/dlls/gdiplus/graphics.c
+++ b/dlls/gdiplus/graphics.c
@@ -4686,6 +4686,11 @@ GpStatus gdip_format_string(HDC hdc,
     StringAlignment halign;
     GpStatus stat = Ok;
     SIZE size;
+    HotkeyPrefix hkprefix;
+    INT *hotkeyprefix_offsets=NULL;
+    INT hotkeyprefix_count=0;
+    INT hotkeyprefix_pos=0, hotkeyprefix_end_pos=0;
+    int seen_prefix=0;
 
     if(length == -1) length = lstrlenW(string);
 
@@ -4698,11 +4703,40 @@ GpStatus gdip_format_string(HDC hdc,
     if (rect->Width >= INT_MAX || rect->Width < 0.5) nwidth = INT_MAX;
     if (rect->Height >= INT_MAX || rect->Height < 0.5) nheight = INT_MAX;
 
+    if (format)
+        hkprefix = format->hkprefix;
+    else
+        hkprefix = HotkeyPrefixNone;
+
+    if (hkprefix == HotkeyPrefixShow)
+    {
+        for (i=0; i<length; i++)
+        {
+            if (string[i] == '&')
+                hotkeyprefix_count++;
+        }
+    }
+
+    if (hotkeyprefix_count)
+        hotkeyprefix_offsets = GdipAlloc(sizeof(INT) * hotkeyprefix_count);
+
+    hotkeyprefix_count = 0;
+
     for(i = 0, j = 0; i < length; i++){
         /* FIXME: This makes the indexes passed to callback inaccurate. */
         if(!isprintW(string[i]) && (string[i] != '\n'))
             continue;
 
+        if (seen_prefix && hkprefix == HotkeyPrefixShow && string[i] != '&')
+            hotkeyprefix_offsets[hotkeyprefix_count++] = j;
+        else if (!seen_prefix && hkprefix != HotkeyPrefixNone && string[i] == '&')
+        {
+            seen_prefix = 1;
+            continue;
+        }
+
+        seen_prefix = 0;
+
         stringdup[j] = string[i];
         j++;
     }
@@ -4777,8 +4811,14 @@ GpStatus gdip_format_string(HDC hdc,
             break;
         }
 
+        for (hotkeyprefix_end_pos=hotkeyprefix_pos; hotkeyprefix_end_pos<hotkeyprefix_count; hotkeyprefix_end_pos++)
+            if (hotkeyprefix_offsets[hotkeyprefix_end_pos] >= sum + lineend)
+                break;
+
         stat = callback(hdc, stringdup, sum, lineend,
-            font, rect, format, lineno, &bounds, user_data);
+            font, rect, format, lineno, &bounds,
+            &hotkeyprefix_offsets[hotkeyprefix_pos],
+            hotkeyprefix_end_pos-hotkeyprefix_pos, user_data);
 
         if (stat != Ok)
             break;
@@ -4787,6 +4827,8 @@ GpStatus gdip_format_string(HDC hdc,
         height += size.cy;
         lineno++;
 
+        hotkeyprefix_pos = hotkeyprefix_end_pos;
+
         if(height > nheight)
             break;
 
@@ -4796,6 +4838,7 @@ GpStatus gdip_format_string(HDC hdc,
     }
 
     GdipFree(stringdup);
+    GdipFree(hotkeyprefix_offsets);
 
     return stat;
 }
@@ -4807,7 +4850,8 @@ struct measure_ranges_args {
 static GpStatus measure_ranges_callback(HDC hdc,
     GDIPCONST WCHAR *string, INT index, INT length, GDIPCONST GpFont *font,
     GDIPCONST RectF *rect, GDIPCONST GpStringFormat *format,
-    INT lineno, const RectF *bounds, void *user_data)
+    INT lineno, const RectF *bounds, INT *underlined_indexes,
+    INT underlined_index_count, void *user_data)
 {
     int i;
     GpStatus stat = Ok;
@@ -4904,7 +4948,8 @@ struct measure_string_args {
 static GpStatus measure_string_callback(HDC hdc,
     GDIPCONST WCHAR *string, INT index, INT length, GDIPCONST GpFont *font,
     GDIPCONST RectF *rect, GDIPCONST GpStringFormat *format,
-    INT lineno, const RectF *bounds, void *user_data)
+    INT lineno, const RectF *bounds, INT *underlined_indexes,
+    INT underlined_index_count, void *user_data)
 {
     struct measure_string_args *args = user_data;
 
@@ -4988,11 +5033,15 @@ struct draw_string_args {
 static GpStatus draw_string_callback(HDC hdc,
     GDIPCONST WCHAR *string, INT index, INT length, GDIPCONST GpFont *font,
     GDIPCONST RectF *rect, GDIPCONST GpStringFormat *format,
-    INT lineno, const RectF *bounds, void *user_data)
+    INT lineno, const RectF *bounds, INT *underlined_indexes,
+    INT underlined_index_count, void *user_data)
 {
     struct draw_string_args *args = user_data;
     PointF position;
 
+    if (underlined_index_count)
+        FIXME("hotkey underlines not drawn yet\n");
+
     position.X = args->x + bounds->X / args->rel_width;
     position.Y = args->y + bounds->Y / args->rel_height + args->ascent;
 
diff --git a/dlls/gdiplus/graphicspath.c b/dlls/gdiplus/graphicspath.c
index 131477e..c41278c 100644
--- a/dlls/gdiplus/graphicspath.c
+++ b/dlls/gdiplus/graphicspath.c
@@ -846,7 +846,8 @@ struct format_string_args
 static GpStatus format_string_callback(HDC dc,
     GDIPCONST WCHAR *string, INT index, INT length, GDIPCONST GpFont *font,
     GDIPCONST RectF *rect, GDIPCONST GpStringFormat *format,
-    INT lineno, const RectF *bounds, void *priv)
+    INT lineno, const RectF *bounds, INT *underlined_indexes,
+    INT underlined_index_count, void *priv)
 {
     static const MAT2 identity = { {0,1}, {0,0}, {0,0}, {0,1} };
     struct format_string_args *args = priv;
@@ -856,6 +857,9 @@ static GpStatus format_string_callback(HDC dc,
     float y = bounds->Y;
     int i;
 
+    if (underlined_index_count)
+        FIXME("hotkey underlines not drawn yet\n");
+
     for (i = index; i < length; ++i)
     {
         GLYPHMETRICS gm;




More information about the wine-cvs mailing list