2 * RichEdit - string operations
4 * Copyright 2004 by Krzysztof Foltman
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 WINE_DEFAULT_DEBUG_CHANNEL(richedit
);
25 static int ME_GetOptimalBuffer(int nLen
)
27 /* FIXME: This seems wasteful for tabs and end of lines strings,
28 * since they have a small fixed length. */
29 return ((sizeof(WCHAR
) * nLen
) + 128) & ~63;
32 /* Create a buffer (uninitialized string) of size nMaxChars */
33 static ME_String
*ME_MakeStringB(int nMaxChars
)
35 ME_String
*s
= ALLOC_OBJ(ME_String
);
38 s
->nBuffer
= ME_GetOptimalBuffer(s
->nLen
+ 1);
39 s
->szData
= ALLOC_N_OBJ(WCHAR
, s
->nBuffer
);
40 s
->szData
[s
->nLen
] = 0;
44 ME_String
*ME_MakeStringN(LPCWSTR szText
, int nMaxChars
)
46 ME_String
*s
= ME_MakeStringB(nMaxChars
);
47 /* Native allows NULL chars */
48 memcpy(s
->szData
, szText
, s
->nLen
* sizeof(WCHAR
));
52 /* Make a string by repeating a char nMaxChars times */
53 ME_String
*ME_MakeStringR(WCHAR cRepeat
, int nMaxChars
)
56 ME_String
*s
= ME_MakeStringB(nMaxChars
);
57 for (i
= 0; i
< nMaxChars
; i
++)
58 s
->szData
[i
] = cRepeat
;
62 void ME_DestroyString(ME_String
*s
)
69 BOOL
ME_InsertString(ME_String
*s
, int ofs
, const WCHAR
*insert
, int len
)
71 DWORD new_len
= s
->nLen
+ len
+ 1;
72 assert( ofs
<= s
->nLen
);
74 if( new_len
> s
->nBuffer
)
76 s
->nBuffer
= ME_GetOptimalBuffer( new_len
);
77 s
->szData
= heap_realloc( s
->szData
, s
->nBuffer
* sizeof(WCHAR
) );
78 if (!s
->szData
) return FALSE
;
81 memmove( s
->szData
+ ofs
+ len
, s
->szData
+ ofs
, (s
->nLen
- ofs
+ 1) * sizeof(WCHAR
) );
82 memcpy( s
->szData
+ ofs
, insert
, len
* sizeof(WCHAR
) );
88 BOOL
ME_AppendString(ME_String
*s
, const WCHAR
*append
, int len
)
90 return ME_InsertString( s
, s
->nLen
, append
, len
);
93 ME_String
*ME_VSplitString(ME_String
*orig
, int charidx
)
97 /*if (charidx<0) charidx = 0;
98 if (charidx>orig->nLen) charidx = orig->nLen;
101 assert(charidx
<=orig
->nLen
);
103 s
= ME_MakeStringN(orig
->szData
+charidx
, orig
->nLen
-charidx
);
104 orig
->nLen
= charidx
;
105 orig
->szData
[charidx
] = '\0';
109 void ME_StrDeleteV(ME_String
*s
, int nVChar
, int nChars
)
111 int end_ofs
= nVChar
+ nChars
;
115 assert(end_ofs
<= s
->nLen
);
117 memmove(s
->szData
+ nVChar
, s
->szData
+ end_ofs
,
118 (s
->nLen
- end_ofs
+ 1) * sizeof(WCHAR
));
123 ME_WordBreakProc(LPWSTR s
, INT start
, INT len
, INT code
)
125 /* FIXME: Native also knows about punctuation */
126 TRACE("s==%s, start==%d, len==%d, code==%d\n",
127 debugstr_wn(s
, len
), start
, len
, code
);
132 return ME_IsWSpace(s
[start
]);
134 case WB_MOVEWORDLEFT
:
135 while (start
&& ME_IsWSpace(s
[start
- 1]))
137 while (start
&& !ME_IsWSpace(s
[start
- 1]))
141 case WB_MOVEWORDRIGHT
:
142 while (start
< len
&& !ME_IsWSpace(s
[start
]))
144 while (start
< len
&& ME_IsWSpace(s
[start
]))
153 ME_CallWordBreakProc(ME_TextEditor
*editor
, WCHAR
*str
, INT len
, INT start
, INT code
)
155 if (!editor
->pfnWordBreak
) {
156 return ME_WordBreakProc(str
, start
, len
, code
);
157 } else if (!editor
->bEmulateVersion10
) {
158 /* MSDN lied about the third parameter for EditWordBreakProc being the number
159 * of characters, it is actually the number of bytes of the string. */
160 return editor
->pfnWordBreak(str
, start
, len
* sizeof(WCHAR
), code
);
163 int buffer_size
= WideCharToMultiByte(CP_ACP
, 0, str
, len
,
164 NULL
, 0, NULL
, NULL
);
165 char *buffer
= heap_alloc(buffer_size
);
166 WideCharToMultiByte(CP_ACP
, 0, str
, len
,
167 buffer
, buffer_size
, NULL
, NULL
);
168 result
= editor
->pfnWordBreak((WCHAR
*)buffer
, start
, buffer_size
, code
);
174 LPWSTR
ME_ToUnicode(LONG codepage
, LPVOID psz
, INT
*len
)
177 if (!psz
) return NULL
;
179 if (codepage
== CP_UNICODE
)
181 *len
= lstrlenW(psz
);
186 int nChars
= MultiByteToWideChar(codepage
, 0, psz
, -1, NULL
, 0);
188 if(!nChars
) return NULL
;
190 if((tmp
= ALLOC_N_OBJ(WCHAR
, nChars
)) != NULL
)
191 *len
= MultiByteToWideChar(codepage
, 0, psz
, -1, tmp
, nChars
) - 1;
196 void ME_EndToUnicode(LONG codepage
, LPVOID psz
)
198 if (codepage
!= CP_UNICODE
)