DrawTextEx reprefixing
Medland, Bill
Bill.Medland at accpac.com
Thu Jan 31 10:54:54 CST 2002
-------------- next part --------------
Bill Medland (medbi01 at accpac.com)
1. Introduce a significant design decision.
2. Recalculate the prefix location if ellipsification alters it. This carefully
does NOT emulate a Microsoft bug in which reprefixing is wrong when the
first character removed by ellipsification is the one that would have been
underlined (under Win98 at least).
Index: wine/dlls/user/text.c
===================================================================
RCS file: /home/wine/wine/dlls/user/text.c,v
retrieving revision 1.20
diff -u -r1.20 text.c
--- wine/dlls/user/text.c 2002/01/29 02:46:09 1.20
+++ wine/dlls/user/text.c 2002/01/31 14:43:36
@@ -28,6 +28,40 @@
/*********************************************************************
*
* DrawText functions
+ *
+ * Design issues
+ * How many buffers to use
+ * While processing in DrawText there are potentially three different forms
+ * of the text that need to be held. How are they best held?
+ * 1. The original text is needed, of course, to see what to display.
+ * 2. The text that will be returned to the user if the DT_MODIFYSTRING is
+ * in effect.
+ * 3. The buffered text that is about to be displayed e.g. the current line.
+ * Typically this will exclude the ampersands used for prefixing etc.
+ *
+ * Complications.
+ * a. If the buffered text to be displayed includes the ampersands then
+ * we will need special measurement and draw functions that will ignore
+ * the ampersands (e.g. by copying to a buffer without the prefix and
+ * then using the normal forms). This may involve less space but may
+ * require more processing. e.g. since a line containing tabs may
+ * contain several underlined characters either we need to carry around
+ * a list of prefix locations or we may need to locate them several
+ * times.
+ * b. If we actually directly modify the "original text" as we go then we
+ * will need some special "caching" to handle the fact that when we
+ * ellipsify the text the ellipsis may modify the next line of text,
+ * which we have not yet processed. (e.g. ellipsification of a W at the
+ * end of a line will overwrite the W, the \n and the first character of
+ * the next line, and a \0 will overwrite the second. Try it!!)
+ *
+ * Option 1. Three separate storages. (To be implemented)
+ * If DT_MODIFYSTRING is in effect then allocate an extra buffer to hold
+ * the edited string in some form, either as the string itself or as some
+ * sort of "edit list" to be applied just before returning.
+ * Use a buffer that holds the ellipsified current line sans ampersands
+ * and accept the need occasionally to recalculate the prefixes (if
+ * DT_EXPANDTABS and not DT_NOPREFIX and not DT_HIDEPREFIX)
*/
#define TAB 9
@@ -51,6 +85,56 @@
static int spacewidth;
static int prefix_offset;
+/*********************************************************************
+ * TEXT_Reprefix
+ *
+ * Reanalyse the text to find the prefixed character. This is called when
+ * wordbreaking or ellipsification has shortened the string such that the
+ * previously noted prefixed character is no longer visible.
+ *
+ * Parameters
+ * str [in] The original string segment (including all characters)
+ * n1 [in] The number of characters visible before the path ellipsis
+ * n2 [in] The number of characters replaced by the path ellipsis
+ * ne [in] The number of characters in the path ellipsis, ignored if
+ * n2 is zero
+ * n3 [in] The number of characters visible after the path ellipsis
+ *
+ * Return Values
+ * The prefix offset within the new string segment (the one that contains the
+ * ellipses and does not contain the prefix characters) (-1 if none)
+ *
+ * Remarks
+ * We know that n1+n2+n3 must be strictly less than the length of the segment
+ * (because otherwise there would be no need to call this function)
+ */
+
+static int TEXT_Reprefix (const WCHAR *str, unsigned int n1, unsigned int n2,
+ unsigned int ne, unsigned int n3)
+{
+ int result = -1;
+ unsigned int i = 0;
+ unsigned int n = n1 + n2 + n3;
+ if (!n2) ne = 0;
+ while (i < n)
+ {
+ if (i == n1)
+ {
+ /* Reached the path ellipsis; jump over it */
+ str += n2;
+ i += n2;
+ if (!n3) break; /* Nothing after the path ellipsis */
+ }
+ if (*str++ == PREFIX)
+ {
+ result = (i < n1) ? i : i - n2 + ne;
+ str++;
+ }
+ else;
+ i++;
+ }
+ return result;
+}
/*********************************************************************
* Return next line of text from a string.
@@ -329,6 +413,8 @@
int totalLen = i_count >= 0 ? i_count : strlenW(str);
int fnameLen = totalLen;
int old_prefix_offset = prefix_offset;
+ int len_before_ellipsis;
+ int len_after_ellipsis;
/* allow room for '...' */
count = min(totalLen+3, countof(line)-3);
@@ -386,17 +472,21 @@
if (fnameLen < len-3) /* some of the path will fit */
{
+ len_before_ellipsis = len-3-fnameLen;
+ len_after_ellipsis = fnameLen;
/* put the ELLIPSIS between the path and filename */
- strncpyW(swapStr, &line[fnameLen+3], len-3-fnameLen);
- swapStr[len-3-fnameLen] = '\0';
+ strncpyW(swapStr, &line[fnameLen+3], len_before_ellipsis);
+ swapStr[len_before_ellipsis] = '\0';
strcatW(swapStr, ELLIPSISW);
strncpyW(swapStr+strlenW(swapStr), &line[3], fnameLen);
}
else
{
/* move the ELLIPSIS to the end */
- strncpyW(swapStr, &line[3], len-3);
- swapStr[len-3] = '\0';
+ len_before_ellipsis = len-3;
+ len_after_ellipsis = 0;
+ strncpyW(swapStr, &line[3], len_before_ellipsis);
+ swapStr[len_before_ellipsis] = '\0';
strcpyW(swapStr+strlenW(swapStr), ELLIPSISW);
}
@@ -404,12 +494,9 @@
line[len] = '\0';
strPtr = NULL;
- /* Note that really we ought to refigure the location of
- * the underline for the prefix; it might be currently set for
- * something we have just ellipsified out.
- * NB We had better do it before modifying the string and
- * loosing the ampersands
- */
+ if (prefix_offset >= 0 &&
+ prefix_offset >= len_before_ellipsis)
+ prefix_offset = TEXT_Reprefix (str, len_before_ellipsis, strlenW(str)-3-len_before_ellipsis-len_after_ellipsis, 3, len_after_ellipsis);
if (flags & DT_MODIFYSTRING)
strcpyW(str, swapStr);
More information about the wine-patches
mailing list