riched20: Add the ability to CharFromPoint to either pick the closest leading edge...
[wine] / dlls / riched20 / editstr.h
1 /*
2  * RichEdit - structures and constant
3  *
4  * Copyright 2004 by Krzysztof Foltman
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #ifndef __EDITSTR_H
22 #define __EDITSTR_H
23
24 #ifndef _WIN32_IE
25 #define _WIN32_IE 0x0400
26 #endif
27
28 #include <assert.h>
29 #include <stdarg.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <limits.h>
33
34 #define COBJMACROS
35 #define NONAMELESSUNION
36 #define NONAMELESSSTRUCT
37
38 #include <windef.h>
39 #include <winbase.h>
40 #include <winnls.h>
41 #include <winnt.h>
42 #include <wingdi.h>
43 #include <winuser.h>
44 #include <richedit.h>
45 #include <commctrl.h>
46 #include <ole2.h>
47 #include <richole.h>
48 #include "imm.h"
49 #include <textserv.h>
50
51 #include "wine/debug.h"
52 #include "wine/list.h"
53
54 #ifdef __i386__
55 extern const struct ITextHostVtbl itextHostStdcallVtbl;
56 #endif /* __i386__ */
57
58 typedef struct tagME_String
59 {
60   WCHAR *szData;
61   int nLen, nBuffer;
62 } ME_String;
63
64 typedef struct tagME_Style
65 {
66   CHARFORMAT2W fmt;
67
68   HFONT hFont; /* cached font for the style */
69   TEXTMETRICW tm; /* cached font metrics for the style */
70   int nRefs; /* reference count */
71 } ME_Style;
72
73 typedef enum {
74   diInvalid,
75   diTextStart, /* start of the text buffer */
76   diParagraph, /* paragraph start */
77   diCell, /* cell start */
78   diRun, /* run (sequence of chars with the same character format) */
79   diStartRow, /* start of the row (line of text on the screen) */
80   diTextEnd, /* end of the text buffer */
81   
82   /********************* these below are meant for finding only *********************/
83   diStartRowOrParagraph, /* 7 */
84   diStartRowOrParagraphOrEnd,
85   diRunOrParagraph,
86   diRunOrStartRow,
87   diParagraphOrEnd,
88   diRunOrParagraphOrEnd, /* 12 */
89 } ME_DIType;
90
91 #define SELECTIONBAR_WIDTH 8
92
93 /******************************** run flags *************************/
94 #define MERF_STYLEFLAGS 0x0FFF
95 /* run contains non-text content, which has its own rules for wrapping, sizing etc */
96 #define MERF_GRAPHICS   0x001
97 /* run is a tab (or, in future, any kind of content whose size is dependent on run position) */
98 #define MERF_TAB        0x002
99 /* run is a cell boundary */
100 #define MERF_ENDCELL    0x004 /* v4.1 */
101
102 #define MERF_NONTEXT (MERF_GRAPHICS | MERF_TAB | MERF_ENDCELL)
103
104 /* run is splittable (contains white spaces in the middle or end) */
105 #define MERF_SPLITTABLE 0x001000
106 /* run starts with whitespaces */
107 #define MERF_STARTWHITE 0x002000
108 /* run ends with whitespaces */
109 #define MERF_ENDWHITE   0x004000
110 /* run is completely made of whitespaces */
111 #define MERF_WHITESPACE 0x008000
112 /* the "end of paragraph" run, contains 1 character */
113 #define MERF_ENDPARA    0x100000
114 /* forcing the "end of row" run, contains 1 character */
115 #define MERF_ENDROW     0x200000
116 /* run is hidden */
117 #define MERF_HIDDEN     0x400000
118 /* start of a table row has an empty paragraph that should be skipped over. */
119 #define MERF_TABLESTART 0x800000 /* v4.1 */
120
121 /* runs with any of these flags set cannot be joined */
122 #define MERF_NOJOIN (MERF_GRAPHICS|MERF_TAB|MERF_ENDPARA|MERF_ENDROW)
123 /* runs that don't contain real text */
124 #define MERF_NOTEXT (MERF_GRAPHICS|MERF_TAB|MERF_ENDPARA|MERF_ENDROW)
125
126 /* those flags are kept when the row is split */
127 #define MERF_SPLITMASK (~(0))
128
129 /******************************** para flags *************************/
130
131 /* this paragraph was already wrapped and hasn't changed, every change resets that flag */
132 #define MEPF_REWRAP   0x01
133 /* v4.1 */
134 #define MEPF_CELL     0x04 /* The paragraph is nested in a cell */
135 #define MEPF_ROWSTART 0x08 /* Hidden empty paragraph at the start of the row */
136 #define MEPF_ROWEND   0x10 /* Visible empty paragraph at the end of the row */
137
138 /******************************** structures *************************/
139
140 struct tagME_DisplayItem;
141
142 typedef struct tagME_Run
143 {
144   ME_Style *style;
145   struct tagME_Paragraph *para; /* ptr to the run's paragraph */
146   int nCharOfs; /* relative to para's offset */
147   int len;      /* length of run's text */
148   int nWidth; /* width of full run, width of leading&trailing ws */
149   int nFlags;
150   int nAscent, nDescent; /* pixels above/below baseline */
151   POINT pt; /* relative to para's position */
152   REOBJECT *ole_obj; /* FIXME: should be a union with strText (at least) */
153 } ME_Run;
154
155 typedef struct tagME_Border
156 {
157   int width;
158   COLORREF colorRef;
159 } ME_Border;
160
161 typedef struct tagME_BorderRect
162 {
163   ME_Border top;
164   ME_Border left;
165   ME_Border bottom;
166   ME_Border right;
167 } ME_BorderRect;
168
169 typedef struct tagME_Paragraph
170 {
171   PARAFORMAT2 *pFmt;
172   ME_String *text;
173
174   struct tagME_DisplayItem *pCell; /* v4.1 */
175   ME_BorderRect border;
176
177   int nCharOfs;
178   int nFlags;
179   POINT pt;
180   int nHeight, nWidth;
181   int nRows;
182   struct tagME_DisplayItem *prev_para, *next_para;
183 } ME_Paragraph;
184
185 typedef struct tagME_Cell /* v4.1 */
186 {
187   int nNestingLevel; /* 0 for normal cells, and greater for nested cells */
188   int nRightBoundary;
189   ME_BorderRect border;
190   POINT pt;
191   int nHeight, nWidth;
192   int yTextOffset; /* The text offset is caused by the largest top border. */
193   struct tagME_DisplayItem *prev_cell, *next_cell, *parent_cell;
194 } ME_Cell;
195
196 typedef struct tagME_Row
197 {
198   int nHeight;
199   int nBaseline;
200   int nWidth;
201   int nLMargin;
202   int nRMargin;
203   POINT pt;
204 } ME_Row;
205
206 /* the display item list layout is like this:
207  * - the document consists of paragraphs
208  * - each paragraph contains at least one run, the last run in the paragraph
209  *   is an end-of-paragraph run
210  * - each formatted paragraph contains at least one row, which corresponds
211  *   to a screen line (that's why there are no rows in an unformatted
212  *   paragraph
213  * - the paragraphs contain "shortcut" pointers to the previous and the next
214  *   paragraph, that makes iteration over paragraphs faster 
215  * - the list starts with diTextStart and ends with diTextEnd
216  */
217
218 typedef struct tagME_DisplayItem
219 {
220   ME_DIType type;
221   struct tagME_DisplayItem *prev, *next;
222   union {
223     ME_Run run;
224     ME_Row row;
225     ME_Cell cell;
226     ME_Paragraph para;
227   } member;
228 } ME_DisplayItem;
229
230 typedef struct tagME_TextBuffer
231 {
232   ME_DisplayItem *pFirst, *pLast;
233   ME_Style *pCharStyle;
234   ME_Style *pDefaultStyle;
235 } ME_TextBuffer;
236
237 typedef struct tagME_Cursor
238 {
239   ME_DisplayItem *pPara;
240   ME_DisplayItem *pRun;
241   int nOffset;
242 } ME_Cursor;
243
244 typedef enum {
245   umAddToUndo,
246   umAddToRedo,
247   umIgnore,
248   umAddBackToUndo
249 } ME_UndoMode;
250
251 enum undo_type
252 {
253     undo_insert_run,
254     undo_delete_run,
255     undo_join_paras,
256     undo_split_para,
257     undo_set_para_fmt,
258     undo_set_char_fmt,
259     undo_end_transaction,          /* marks the end of a group of changes for undo */
260     undo_potential_end_transaction /* allows grouping typed chars for undo */
261 };
262
263 struct insert_run_item
264 {
265     int pos, len;
266     WCHAR *str;
267     ME_Style *style;
268     DWORD flags;
269 };
270
271 struct delete_run_item
272 {
273     int pos, len;
274 };
275
276 struct join_paras_item
277 {
278     int pos;
279 };
280
281 struct split_para_item
282 {
283     int pos;
284     PARAFORMAT2 fmt;
285     ME_BorderRect border;
286     ME_String *eol_str;
287     DWORD flags;
288     ME_BorderRect cell_border;
289     int cell_right_boundary;
290 };
291
292 struct set_para_fmt_item
293 {
294     int pos;
295     PARAFORMAT2 fmt;
296     ME_BorderRect border;
297 };
298
299 struct set_char_fmt_item
300 {
301     int pos, len;
302     CHARFORMAT2W fmt;
303 };
304
305 struct undo_item
306 {
307     struct list entry;
308     enum undo_type type;
309     union
310     {
311         struct insert_run_item insert_run;
312         struct delete_run_item delete_run;
313         struct join_paras_item join_paras;
314         struct split_para_item split_para;
315         struct set_para_fmt_item set_para_fmt;
316         struct set_char_fmt_item set_char_fmt;
317     } u;
318 };
319
320 typedef enum {
321   stPosition = 0,
322   stWord,
323   stLine,
324   stParagraph,
325   stDocument
326 } ME_SelectionType;
327
328 typedef struct tagME_FontTableItem {
329   BYTE bCharSet;
330   WCHAR *szFaceName;
331 } ME_FontTableItem;
332
333
334 #define STREAMIN_BUFFER_SIZE 4096 /* M$ compatibility */
335
336 struct tagME_InStream {
337   EDITSTREAM *editstream;
338   DWORD dwSize;
339   DWORD dwUsed;
340   char buffer[STREAMIN_BUFFER_SIZE];
341 };
342 typedef struct tagME_InStream ME_InStream;
343
344
345 #define STREAMOUT_BUFFER_SIZE 4096
346 #define STREAMOUT_FONTTBL_SIZE 8192
347 #define STREAMOUT_COLORTBL_SIZE 1024
348
349 typedef struct tagME_OutStream {
350   EDITSTREAM *stream;
351   char buffer[STREAMOUT_BUFFER_SIZE];
352   UINT pos, written;
353   UINT nCodePage;
354   UINT nFontTblLen;
355   ME_FontTableItem fonttbl[STREAMOUT_FONTTBL_SIZE];
356   UINT nColorTblLen;
357   COLORREF colortbl[STREAMOUT_COLORTBL_SIZE];
358   UINT nDefaultFont;
359   UINT nDefaultCodePage;
360   /* nNestingLevel = 0 means we aren't in a cell, 1 means we are in a cell,
361    * an greater numbers mean we are in a cell nested within a cell. */
362   UINT nNestingLevel;
363 } ME_OutStream;
364
365 typedef struct tagME_FontCacheItem
366 {
367   LOGFONTW lfSpecs;
368   HFONT hFont;
369   int nRefs;
370   int nAge;
371 } ME_FontCacheItem;
372
373 #define HFONT_CACHE_SIZE 10
374
375 typedef struct tagME_TextEditor
376 {
377   HWND hWnd, hwndParent;
378   ITextHost *texthost;
379   BOOL bEmulateVersion10;
380   ME_TextBuffer *pBuffer;
381   ME_Cursor *pCursors;
382   DWORD styleFlags;
383   DWORD exStyleFlags;
384   int nCursors;
385   SIZE sizeWindow;
386   int nTotalLength, nLastTotalLength;
387   int nTotalWidth, nLastTotalWidth;
388   int nAvailWidth; /* 0 = wrap to client area, else wrap width in twips */
389   int nUDArrowX;
390   COLORREF rgbBackColor;
391   HBRUSH hbrBackground;
392   BOOL bCaretAtEnd;
393   int nEventMask;
394   int nModifyStep;
395   struct list undo_stack;
396   struct list redo_stack;
397   int nUndoStackSize;
398   int nUndoLimit;
399   ME_UndoMode nUndoMode;
400   int nParagraphs;
401   int nLastSelStart, nLastSelEnd;
402   ME_DisplayItem *pLastSelStartPara, *pLastSelEndPara;
403   ME_FontCacheItem pFontCache[HFONT_CACHE_SIZE];
404   int nZoomNumerator, nZoomDenominator;
405   RECT prevClientRect;
406   RECT rcFormat;
407   BOOL bDefaultFormatRect;
408   BOOL bWordWrap;
409   int nTextLimit;
410   EDITWORDBREAKPROCW pfnWordBreak;
411   LPRICHEDITOLECALLBACK lpOleCallback;
412   /*TEXTMODE variable; contains only one of each of the following options:
413    *TM_RICHTEXT or TM_PLAINTEXT
414    *TM_SINGLELEVELUNDO or TM_MULTILEVELUNDO
415    *TM_SINGLECODEPAGE or TM_MULTICODEPAGE*/
416   int mode;
417   BOOL bHideSelection;
418   BOOL AutoURLDetect_bEnable;
419   WCHAR cPasswordMask;
420   BOOL bHaveFocus;
421   BOOL bDialogMode; /* Indicates that we are inside a dialog window */
422   /*for IME */
423   int imeStartIndex;
424   DWORD selofs; /* The size of the selection bar on the left side of control */
425   ME_SelectionType nSelectionType;
426
427   /* Track previous notified selection */
428   CHARRANGE notified_cr;
429
430   /* Cache previously set scrollbar info */
431   SCROLLINFO vert_si, horz_si;
432
433   BOOL bMouseCaptured;
434 } ME_TextEditor;
435
436 typedef struct tagME_Context
437 {
438   HDC hDC;
439   POINT pt;
440   RECT rcView;
441   SIZE dpi;
442   int nAvailWidth;
443
444   /* those are valid inside ME_WrapTextParagraph and related */
445   ME_TextEditor *editor;
446 } ME_Context;
447
448 typedef struct tagME_WrapContext
449 {
450   ME_Style *style;
451   ME_Context *context;
452   int nLeftMargin, nRightMargin, nFirstMargin;
453   int nAvailWidth;
454   int nRow;
455   POINT pt;
456   BOOL bOverflown, bWordWrap;
457   ME_DisplayItem *pPara;
458   ME_DisplayItem *pRowStart;
459
460   ME_DisplayItem *pLastSplittableRun;
461 } ME_WrapContext;
462
463 #endif