ReactOS  0.4.14-dev-49-gfb4591c
paint.c
Go to the documentation of this file.
1 /*
2  * RichEdit - painting functions
3  *
4  * Copyright 2004 by Krzysztof Foltman
5  * Copyright 2005 by Phil Krylov
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21 
22 #include "editor.h"
23 
25 
26 static void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph);
27 
28 void ME_PaintContent(ME_TextEditor *editor, HDC hDC, const RECT *rcUpdate)
29 {
31  ME_Context c;
32  int ys, ye;
33  HRGN oldRgn;
34 
35  oldRgn = CreateRectRgn(0, 0, 0, 0);
36  if (!GetClipRgn(hDC, oldRgn))
37  {
38  DeleteObject(oldRgn);
39  oldRgn = NULL;
40  }
41  IntersectClipRect(hDC, rcUpdate->left, rcUpdate->top,
42  rcUpdate->right, rcUpdate->bottom);
43 
44  ME_InitContext(&c, editor, hDC);
46  ME_MoveCaret(editor);
47  item = editor->pBuffer->pFirst->next;
48  /* This context point is an offset for the paragraph positions stored
49  * during wrapping. It shouldn't be modified during painting. */
50  c.pt.x = c.rcView.left - editor->horz_si.nPos;
51  c.pt.y = c.rcView.top - editor->vert_si.nPos;
52  while(item != editor->pBuffer->pLast)
53  {
54  assert(item->type == diParagraph);
55 
56  ys = c.pt.y + item->member.para.pt.y;
57  if (item->member.para.pCell
58  != item->member.para.next_para->member.para.pCell)
59  {
60  ME_Cell *cell = NULL;
61  cell = &ME_FindItemBack(item->member.para.next_para, diCell)->member.cell;
62  ye = c.pt.y + cell->pt.y + cell->nHeight;
63  } else {
64  ye = ys + item->member.para.nHeight;
65  }
66  if (item->member.para.pCell && !(item->member.para.nFlags & MEPF_ROWEND) &&
67  item->member.para.pCell != item->member.para.prev_para->member.para.pCell)
68  {
69  /* the border shifts the text down */
70  ys -= item->member.para.pCell->member.cell.yTextOffset;
71  }
72 
73  /* Draw the paragraph if any of the paragraph is in the update region. */
74  if (ys < rcUpdate->bottom && ye > rcUpdate->top)
76  item = item->member.para.next_para;
77  }
78  if (c.pt.y + editor->nTotalLength < c.rcView.bottom)
79  {
80  /* Fill space after the end of the text. */
81  RECT rc;
82  rc.top = c.pt.y + editor->nTotalLength;
83  rc.left = c.rcView.left;
84  rc.bottom = c.rcView.bottom;
85  rc.right = c.rcView.right;
86 
87  IntersectRect(&rc, &rc, rcUpdate);
88 
89  if (!IsRectEmpty(&rc))
90  FillRect(hDC, &rc, c.editor->hbrBackground);
91  }
92  if (editor->nTotalLength != editor->nLastTotalLength ||
93  editor->nTotalWidth != editor->nLastTotalWidth)
94  ME_SendRequestResize(editor, FALSE);
95  editor->nLastTotalLength = editor->nTotalLength;
96  editor->nLastTotalWidth = editor->nTotalWidth;
97 
98  SelectClipRgn(hDC, oldRgn);
99  if (oldRgn)
100  DeleteObject(oldRgn);
101 
102  c.hDC = NULL;
104 }
105 
107 {
108  if (ME_WrapMarkedParagraphs(editor))
109  {
110  ME_UpdateScrollBar(editor);
111  FIXME("ME_Repaint had to call ME_WrapMarkedParagraphs\n");
112  }
114 }
115 
116 void ME_UpdateRepaint(ME_TextEditor *editor, BOOL update_now)
117 {
118  /* Should be called whenever the contents of the control have changed */
119  BOOL wrappedParagraphs;
120 
121  wrappedParagraphs = ME_WrapMarkedParagraphs(editor);
122  if (wrappedParagraphs)
123  ME_UpdateScrollBar(editor);
124 
125  /* Ensure that the cursor is visible */
126  ME_EnsureVisible(editor, &editor->pCursors[0]);
127 
128  ITextHost_TxViewChange(editor->texthost, update_now);
129 
130  ME_SendSelChange(editor);
131 
132  /* send EN_CHANGE if the event mask asks for it */
133  if(editor->nEventMask & ENM_CHANGE)
134  {
135  editor->nEventMask &= ~ENM_CHANGE;
136  ME_SendOldNotify(editor, EN_CHANGE);
137  editor->nEventMask |= ENM_CHANGE;
138  }
139 }
140 
141 void
143 {
144  /* RewrapRepaint should be called whenever the control has changed in
145  * looks, but not content. Like resizing. */
146 
147  ME_MarkAllForWrapping(editor);
148  ME_WrapMarkedParagraphs(editor);
149  ME_UpdateScrollBar(editor);
150  ME_Repaint(editor);
151 }
152 
153 int ME_twips2pointsX(const ME_Context *c, int x)
154 {
155  if (c->editor->nZoomNumerator == 0)
156  return x * c->dpi.cx / 1440;
157  else
158  return x * c->dpi.cx * c->editor->nZoomNumerator / 1440 / c->editor->nZoomDenominator;
159 }
160 
161 int ME_twips2pointsY(const ME_Context *c, int y)
162 {
163  if (c->editor->nZoomNumerator == 0)
164  return y * c->dpi.cy / 1440;
165  else
166  return y * c->dpi.cy * c->editor->nZoomNumerator / 1440 / c->editor->nZoomDenominator;
167 }
168 
169 
170 static int calc_y_offset( const ME_Context *c, ME_Style *style )
171 {
172  int offs = 0, twips = 0;
173 
174  if ((style->fmt.dwMask & style->fmt.dwEffects) & CFM_OFFSET)
175  twips = style->fmt.yOffset;
176 
177  if ((style->fmt.dwMask & style->fmt.dwEffects) & (CFM_SUPERSCRIPT | CFM_SUBSCRIPT))
178  {
179  if (style->fmt.dwEffects & CFE_SUPERSCRIPT) twips = style->fmt.yHeight/3;
180  if (style->fmt.dwEffects & CFE_SUBSCRIPT) twips = -style->fmt.yHeight/12;
181  }
182 
183  if (twips) offs = ME_twips2pointsY( c, twips );
184 
185  return offs;
186 }
187 
189 {
190  COLORREF color;
191 
192  if (highlight)
193  color = ITextHost_TxGetSysColor( c->editor->texthost, COLOR_HIGHLIGHTTEXT );
194  else if ((style->fmt.dwMask & CFM_LINK) && (style->fmt.dwEffects & CFE_LINK))
195  color = RGB(0,0,255);
196  else if ((style->fmt.dwMask & CFM_COLOR) && (style->fmt.dwEffects & CFE_AUTOCOLOR))
197  color = ITextHost_TxGetSysColor( c->editor->texthost, COLOR_WINDOWTEXT );
198  else
199  color = style->fmt.crTextColor;
200 
201  return color;
202 }
203 
205 {
206  COLORREF color;
207 
208  if (highlight)
209  color = ITextHost_TxGetSysColor( c->editor->texthost, COLOR_HIGHLIGHT );
210  else if ( (style->fmt.dwMask & CFM_BACKCOLOR)
211  && !(style->fmt.dwEffects & CFE_AUTOBACKCOLOR) )
212  color = style->fmt.crBackColor;
213  else
214  color = ITextHost_TxGetSysColor( c->editor->texthost, COLOR_WINDOW );
215 
216  return color;
217 }
218 
220 {
221  if (style->fmt.dwEffects & CFE_LINK)
222  return CreatePen( PS_SOLID, 1, color );
223 
224  /* Choose the pen type for underlining the text. */
225  if (style->fmt.dwEffects & CFE_UNDERLINE)
226  {
227  switch (style->fmt.bUnderlineType)
228  {
229  case CFU_UNDERLINE:
230  case CFU_UNDERLINEWORD: /* native seems to map it to simple underline (MSDN) */
231  case CFU_UNDERLINEDOUBLE: /* native seems to map it to simple underline (MSDN) */
232  return CreatePen( PS_SOLID, 1, color );
233  case CFU_UNDERLINEDOTTED:
234  return CreatePen( PS_DOT, 1, color );
235  default:
236  FIXME( "Unknown underline type (%u)\n", style->fmt.bUnderlineType );
237  /* fall through */
238  case CFU_CF1UNDERLINE: /* this type is supported in the font, do nothing */
239  case CFU_UNDERLINENONE:
240  break;
241  }
242  }
243  return NULL;
244 }
245 
246 static void draw_underline( ME_Context *c, ME_Run *run, int x, int y, COLORREF color )
247 {
248  HPEN pen;
249 
250  pen = get_underline_pen( run->style, color );
251  if (pen)
252  {
253  HPEN old_pen = SelectObject( c->hDC, pen );
254  MoveToEx( c->hDC, x, y + 1, NULL );
255  LineTo( c->hDC, x + run->nWidth, y + 1 );
256  SelectObject( c->hDC, old_pen );
257  DeleteObject( pen );
258  }
259  return;
260 }
261 
262 /*********************************************************************
263  * draw_space
264  *
265  * Draw the end-of-paragraph or tab space.
266  *
267  * If actually_draw is TRUE then ensure any underline is drawn.
268  */
269 static void draw_space( ME_Context *c, ME_Run *run, int x, int y,
270  BOOL selected, BOOL actually_draw, int ymin, int cy )
271 {
272  HDC hdc = c->hDC;
273  BOOL old_style_selected = FALSE;
274  RECT rect;
275  COLORREF back_color = 0;
276 
277  SetRect( &rect, x, ymin, x + run->nWidth, ymin + cy );
278 
279  if (c->editor->bHideSelection || (!c->editor->bHaveFocus &&
280  !(c->editor->styleFlags & ES_NOHIDESEL))) selected = FALSE;
281  if (c->editor->bEmulateVersion10)
282  {
283  old_style_selected = selected;
284  selected = FALSE;
285  }
286 
287  if (selected)
288  back_color = ITextHost_TxGetSysColor( c->editor->texthost, COLOR_HIGHLIGHT );
289 
290  if (actually_draw)
291  {
292  COLORREF text_color = get_text_color( c, run->style, selected );
293  COLORREF old_text, old_back;
294  HFONT old_font = NULL;
295  int y_offset = calc_y_offset( c, run->style );
296  static const WCHAR space[1] = {' '};
297 
298  old_font = ME_SelectStyleFont( c, run->style );
299  old_text = SetTextColor( hdc, text_color );
300  if (selected) old_back = SetBkColor( hdc, back_color );
301 
302  ExtTextOutW( hdc, x, y - y_offset, selected ? ETO_OPAQUE : 0, &rect, space, 1, &run->nWidth );
303 
304  if (selected) SetBkColor( hdc, old_back );
305  SetTextColor( hdc, old_text );
306  ME_UnselectStyleFont( c, run->style, old_font );
307 
308  draw_underline( c, run, x, y - y_offset, text_color );
309  }
310  else if (selected)
311  {
312  HBRUSH brush = CreateSolidBrush( back_color );
313  FillRect( hdc, &rect, brush );
314  DeleteObject( brush );
315  }
316 
317  if (old_style_selected)
318  PatBlt( hdc, x, ymin, run->nWidth, cy, DSTINVERT );
319 }
320 
321 static void get_selection_rect( ME_Context *c, ME_Run *run, int from, int to, int cy, RECT *r )
322 {
323  from = max( 0, from );
324  to = min( run->len, to );
325  r->left = ME_PointFromCharContext( c, run, from, TRUE );
326  r->top = 0;
327  r->right = ME_PointFromCharContext( c, run, to, TRUE );
328  r->bottom = cy;
329  return;
330 }
331 
332 static void draw_text( ME_Context *c, ME_Run *run, int x, int y, BOOL selected, RECT *sel_rect )
333 {
334  COLORREF text_color = get_text_color( c, run->style, selected );
335  COLORREF back_color = get_back_color( c, run->style, selected );
336  COLORREF old_text, old_back = 0;
337  const WCHAR *text = get_text( run, 0 );
338  ME_String *masked = NULL;
339  const BOOL paint_bg = ( selected
340  || ( ( run->style->fmt.dwMask & CFM_BACKCOLOR )
341  && !(CFE_AUTOBACKCOLOR & run->style->fmt.dwEffects) )
342  );
343 
344  if (c->editor->cPasswordMask)
345  {
346  masked = ME_MakeStringR( c->editor->cPasswordMask, run->len );
347  text = masked->szData;
348  }
349 
350  old_text = SetTextColor( c->hDC, text_color );
351  if (paint_bg) old_back = SetBkColor( c->hDC, back_color );
352 
353  if (run->para->nFlags & MEPF_COMPLEX)
354  ScriptTextOut( c->hDC, &run->style->script_cache, x, y, paint_bg ? ETO_OPAQUE : 0, sel_rect,
355  &run->script_analysis, NULL, 0, run->glyphs, run->num_glyphs, run->advances,
356  NULL, run->offsets );
357  else
358  ExtTextOutW( c->hDC, x, y, paint_bg ? ETO_OPAQUE : 0, sel_rect, text, run->len, NULL );
359 
360  if (paint_bg) SetBkColor( c->hDC, old_back );
361  SetTextColor( c->hDC, old_text );
362 
363  draw_underline( c, run, x, y, text_color );
364 
365  ME_DestroyString( masked );
366  return;
367 }
368 
369 
370 static void ME_DrawTextWithStyle(ME_Context *c, ME_Run *run, int x, int y,
371  int nSelFrom, int nSelTo, int ymin, int cy)
372 {
373  HDC hDC = c->hDC;
374  HGDIOBJ hOldFont;
375  int yOffset = 0;
376  BOOL selected = (nSelFrom < run->len && nSelTo >= 0
377  && nSelFrom < nSelTo && !c->editor->bHideSelection &&
378  (c->editor->bHaveFocus || (c->editor->styleFlags & ES_NOHIDESEL)));
379  BOOL old_style_selected = FALSE;
380  RECT sel_rect;
381  HRGN clip = NULL, sel_rgn = NULL;
382 
383  yOffset = calc_y_offset( c, run->style );
384 
385  if (selected)
386  {
387  get_selection_rect( c, run, nSelFrom, nSelTo, cy, &sel_rect );
388  OffsetRect( &sel_rect, x, ymin );
389 
390  if (c->editor->bEmulateVersion10)
391  {
392  old_style_selected = TRUE;
393  selected = FALSE;
394  }
395  else
396  {
397  sel_rgn = CreateRectRgnIndirect( &sel_rect );
398  clip = CreateRectRgn( 0, 0, 0, 0 );
399  if (GetClipRgn( hDC, clip ) != 1)
400  {
401  DeleteObject( clip );
402  clip = NULL;
403  }
404  }
405  }
406 
407  hOldFont = ME_SelectStyleFont( c, run->style );
408 
409  if (sel_rgn) ExtSelectClipRgn( hDC, sel_rgn, RGN_DIFF );
410 
411  if (!(run->style->fmt.dwEffects & CFE_AUTOBACKCOLOR)
412  && (run->style->fmt.dwMask & CFM_BACKCOLOR) )
413  {
414  RECT tmp_rect;
415  get_selection_rect( c, run, 0, run->len, cy, &tmp_rect );
416  OffsetRect( &tmp_rect, x, ymin );
417  draw_text( c, run, x, y - yOffset, FALSE, &tmp_rect );
418  }
419  else
420  draw_text( c, run, x, y - yOffset, FALSE, NULL );
421 
422  if (sel_rgn)
423  {
424  ExtSelectClipRgn( hDC, clip, RGN_COPY );
425  ExtSelectClipRgn( hDC, sel_rgn, RGN_AND );
426  draw_text( c, run, x, y - yOffset, TRUE, &sel_rect );
427  ExtSelectClipRgn( hDC, clip, RGN_COPY );
428  if (clip) DeleteObject( clip );
429  DeleteObject( sel_rgn );
430  }
431 
432  if (old_style_selected)
433  PatBlt( hDC, sel_rect.left, ymin, sel_rect.right - sel_rect.left, cy, DSTINVERT );
434 
435  ME_UnselectStyleFont(c, run->style, hOldFont);
436 }
437 
438 static void ME_DebugWrite(HDC hDC, const POINT *pt, LPCWSTR szText) {
441  COLORREF color = SetTextColor(hDC, RGB(128,128,128));
442  TextOutW(hDC, pt->x, pt->y, szText, lstrlenW(szText));
446 }
447 
448 static void ME_DrawRun(ME_Context *c, int x, int y, ME_DisplayItem *rundi, ME_Paragraph *para)
449 {
450  ME_Run *run = &rundi->member.run;
452  int runofs = run->nCharOfs+para->nCharOfs;
453  int nSelFrom, nSelTo;
454 
455  if (run->nFlags & MERF_HIDDEN)
456  return;
457 
458  start = ME_FindItemBack(rundi, diStartRow);
459  ME_GetSelectionOfs(c->editor, &nSelFrom, &nSelTo);
460 
461  /* Draw selected end-of-paragraph mark */
462  if (run->nFlags & MERF_ENDPARA)
463  {
464  if (runofs >= nSelFrom && runofs < nSelTo)
465  {
466  draw_space( c, run, x, y, TRUE, FALSE,
467  c->pt.y + para->pt.y + start->member.row.pt.y,
468  start->member.row.nHeight );
469  }
470  return;
471  }
472 
473  if (run->nFlags & (MERF_TAB | MERF_ENDCELL))
474  {
475  BOOL selected = runofs >= nSelFrom && runofs < nSelTo;
476 
477  draw_space( c, run, x, y, selected, TRUE,
478  c->pt.y + para->pt.y + start->member.row.pt.y,
479  start->member.row.nHeight );
480  return;
481  }
482 
483  if (run->nFlags & MERF_GRAPHICS)
484  ME_DrawOLE(c, x, y, run, (runofs >= nSelFrom) && (runofs < nSelTo));
485  else
486  {
487  ME_DrawTextWithStyle(c, run, x, y, nSelFrom - runofs, nSelTo - runofs,
488  c->pt.y + para->pt.y + start->member.row.pt.y,
489  start->member.row.nHeight);
490  }
491 }
492 
493 /* The documented widths are in points (72 dpi), but converting them to
494  * 96 dpi (standard display resolution) avoids dealing with fractions. */
495 static const struct {unsigned width : 8, pen_style : 4, dble : 1;} border_details[] = {
496  /* none */ {0, PS_SOLID, FALSE},
497  /* 3/4 */ {1, PS_SOLID, FALSE},
498  /* 1 1/2 */ {2, PS_SOLID, FALSE},
499  /* 2 1/4 */ {3, PS_SOLID, FALSE},
500  /* 3 */ {4, PS_SOLID, FALSE},
501  /* 4 1/2 */ {6, PS_SOLID, FALSE},
502  /* 6 */ {8, PS_SOLID, FALSE},
503  /* 3/4 double */ {1, PS_SOLID, TRUE},
504  /* 1 1/2 double */ {2, PS_SOLID, TRUE},
505  /* 2 1/4 double */ {3, PS_SOLID, TRUE},
506  /* 3/4 gray */ {1, PS_DOT /* FIXME */, FALSE},
507  /* 1 1/2 dashed */ {2, PS_DASH, FALSE},
508 };
509 
510 static const COLORREF pen_colors[16] = {
511  /* Black */ RGB(0x00, 0x00, 0x00), /* Blue */ RGB(0x00, 0x00, 0xFF),
512  /* Cyan */ RGB(0x00, 0xFF, 0xFF), /* Green */ RGB(0x00, 0xFF, 0x00),
513  /* Magenta */ RGB(0xFF, 0x00, 0xFF), /* Red */ RGB(0xFF, 0x00, 0x00),
514  /* Yellow */ RGB(0xFF, 0xFF, 0x00), /* White */ RGB(0xFF, 0xFF, 0xFF),
515  /* Dark blue */ RGB(0x00, 0x00, 0x80), /* Dark cyan */ RGB(0x00, 0x80, 0x80),
516  /* Dark green */ RGB(0x00, 0x80, 0x80), /* Dark magenta */ RGB(0x80, 0x00, 0x80),
517  /* Dark red */ RGB(0x80, 0x00, 0x00), /* Dark yellow */ RGB(0x80, 0x80, 0x00),
518  /* Dark gray */ RGB(0x80, 0x80, 0x80), /* Light gray */ RGB(0xc0, 0xc0, 0xc0),
519 };
520 
521 static int ME_GetBorderPenWidth(const ME_Context* c, int idx)
522 {
523  int width = border_details[idx].width;
524 
525  if (c->dpi.cx != 96)
526  width = MulDiv(width, c->dpi.cx, 96);
527 
528  if (c->editor->nZoomNumerator != 0)
529  width = MulDiv(width, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
530 
531  return width;
532 }
533 
535 {
536  int idx = (flags >> 8) & 0xF;
537  int width;
538 
539  if (idx >= ARRAY_SIZE(border_details))
540  {
541  FIXME("Unsupported border value %d\n", idx);
542  return 0;
543  }
545  if (border_details[idx].dble) width = width * 2 + 1;
546  return width;
547 }
548 
549 static void ME_DrawParaDecoration(ME_Context* c, ME_Paragraph* para, int y, RECT* bounds)
550 {
551  int idx, border_width, top_border, bottom_border;
552  RECT rc;
553  BOOL hasParaBorder;
554 
555  SetRectEmpty(bounds);
556  if (!(para->fmt.dwMask & (PFM_BORDER | PFM_SPACEBEFORE | PFM_SPACEAFTER))) return;
557 
558  border_width = top_border = bottom_border = 0;
559  idx = (para->fmt.wBorders >> 8) & 0xF;
560  hasParaBorder = (!(c->editor->bEmulateVersion10 &&
561  para->fmt.dwMask & PFM_TABLE &&
562  para->fmt.wEffects & PFE_TABLE) &&
563  (para->fmt.dwMask & PFM_BORDER) &&
564  idx != 0 &&
565  (para->fmt.wBorders & 0xF));
566  if (hasParaBorder)
567  {
568  /* FIXME: wBorders is not stored as MSDN says in v1.0 - 4.1 of richedit
569  * controls. It actually stores the paragraph or row border style. Although
570  * the value isn't used for drawing, it is used for streaming out rich text.
571  *
572  * wBorders stores the border style for each side (top, left, bottom, right)
573  * using nibble (4 bits) to store each border style. The rich text format
574  * control words, and their associated value are the following:
575  * \brdrdash 0
576  * \brdrdashsm 1
577  * \brdrdb 2
578  * \brdrdot 3
579  * \brdrhair 4
580  * \brdrs 5
581  * \brdrth 6
582  * \brdrtriple 7
583  *
584  * The order of the sides stored actually differs from v1.0 to 3.0 and v4.1.
585  * The mask corresponding to each side for the version are the following:
586  * mask v1.0-3.0 v4.1
587  * 0x000F top left
588  * 0x00F0 left top
589  * 0x0F00 bottom right
590  * 0xF000 right bottom
591  */
592  if (para->fmt.wBorders & 0x00B0)
593  FIXME("Unsupported border flags %x\n", para->fmt.wBorders);
594  border_width = ME_GetParaBorderWidth(c, para->fmt.wBorders);
595  if (para->fmt.wBorders & 4) top_border = border_width;
596  if (para->fmt.wBorders & 8) bottom_border = border_width;
597  }
598 
599  if (para->fmt.dwMask & PFM_SPACEBEFORE)
600  {
601  rc.left = c->rcView.left;
602  rc.right = c->rcView.right;
603  rc.top = y;
604  bounds->top = ME_twips2pointsY(c, para->fmt.dySpaceBefore);
605  rc.bottom = y + bounds->top + top_border;
606  FillRect(c->hDC, &rc, c->editor->hbrBackground);
607  }
608 
609  if (para->fmt.dwMask & PFM_SPACEAFTER)
610  {
611  rc.left = c->rcView.left;
612  rc.right = c->rcView.right;
613  rc.bottom = y + para->nHeight;
614  bounds->bottom = ME_twips2pointsY(c, para->fmt.dySpaceAfter);
615  rc.top = rc.bottom - bounds->bottom - bottom_border;
616  FillRect(c->hDC, &rc, c->editor->hbrBackground);
617  }
618 
619  /* Native richedit doesn't support paragraph borders in v1.0 - 4.1,
620  * but might support it in later versions. */
621  if (hasParaBorder) {
622  int pen_width, rightEdge;
623  COLORREF pencr;
624  HPEN pen = NULL, oldpen = NULL;
625  POINT pt;
626 
627  if (para->fmt.wBorders & 64) /* autocolor */
628  pencr = ITextHost_TxGetSysColor(c->editor->texthost,
630  else
631  pencr = pen_colors[(para->fmt.wBorders >> 12) & 0xF];
632 
633  rightEdge = c->pt.x + max(c->editor->sizeWindow.cx,
634  c->editor->nTotalWidth);
635 
636  pen_width = ME_GetBorderPenWidth(c, idx);
637  pen = CreatePen(border_details[idx].pen_style, pen_width, pencr);
638  oldpen = SelectObject(c->hDC, pen);
639  MoveToEx(c->hDC, 0, 0, &pt);
640 
641  /* before & after spaces are not included in border */
642 
643  /* helper to draw the double lines in case of corner */
644 #define DD(x) ((para->fmt.wBorders & (x)) ? (pen_width + 1) : 0)
645 
646  if (para->fmt.wBorders & 1)
647  {
648  MoveToEx(c->hDC, c->pt.x, y + bounds->top, NULL);
649  LineTo(c->hDC, c->pt.x, y + para->nHeight - bounds->bottom);
650  if (border_details[idx].dble) {
651  rc.left = c->pt.x + 1;
652  rc.right = rc.left + border_width;
653  rc.top = y + bounds->top;
654  rc.bottom = y + para->nHeight - bounds->bottom;
655  FillRect(c->hDC, &rc, c->editor->hbrBackground);
656  MoveToEx(c->hDC, c->pt.x + pen_width + 1, y + bounds->top + DD(4), NULL);
657  LineTo(c->hDC, c->pt.x + pen_width + 1, y + para->nHeight - bounds->bottom - DD(8));
658  }
659  bounds->left += border_width;
660  }
661  if (para->fmt.wBorders & 2)
662  {
663  MoveToEx(c->hDC, rightEdge - 1, y + bounds->top, NULL);
664  LineTo(c->hDC, rightEdge - 1, y + para->nHeight - bounds->bottom);
665  if (border_details[idx].dble) {
666  rc.left = rightEdge - pen_width - 1;
667  rc.right = rc.left + pen_width;
668  rc.top = y + bounds->top;
669  rc.bottom = y + para->nHeight - bounds->bottom;
670  FillRect(c->hDC, &rc, c->editor->hbrBackground);
671  MoveToEx(c->hDC, rightEdge - 1 - pen_width - 1, y + bounds->top + DD(4), NULL);
672  LineTo(c->hDC, rightEdge - 1 - pen_width - 1, y + para->nHeight - bounds->bottom - DD(8));
673  }
674  bounds->right += border_width;
675  }
676  if (para->fmt.wBorders & 4)
677  {
678  MoveToEx(c->hDC, c->pt.x, y + bounds->top, NULL);
679  LineTo(c->hDC, rightEdge, y + bounds->top);
680  if (border_details[idx].dble) {
681  MoveToEx(c->hDC, c->pt.x + DD(1), y + bounds->top + pen_width + 1, NULL);
682  LineTo(c->hDC, rightEdge - DD(2), y + bounds->top + pen_width + 1);
683  }
684  bounds->top += border_width;
685  }
686  if (para->fmt.wBorders & 8)
687  {
688  MoveToEx(c->hDC, c->pt.x, y + para->nHeight - bounds->bottom - 1, NULL);
689  LineTo(c->hDC, rightEdge, y + para->nHeight - bounds->bottom - 1);
690  if (border_details[idx].dble) {
691  MoveToEx(c->hDC, c->pt.x + DD(1), y + para->nHeight - bounds->bottom - 1 - pen_width - 1, NULL);
692  LineTo(c->hDC, rightEdge - DD(2), y + para->nHeight - bounds->bottom - 1 - pen_width - 1);
693  }
694  bounds->bottom += border_width;
695  }
696 #undef DD
697 
698  MoveToEx(c->hDC, pt.x, pt.y, NULL);
699  SelectObject(c->hDC, oldpen);
700  DeleteObject(pen);
701  }
702 }
703 
705 {
706  ME_Paragraph *para = &paragraph->member.para;
707  if (!c->editor->bEmulateVersion10) /* v4.1 */
708  {
709  if (para->pCell)
710  {
711  RECT rc;
712  ME_Cell *cell = &para->pCell->member.cell;
713  ME_DisplayItem *paraAfterRow;
714  HPEN pen, oldPen;
715  LOGBRUSH logBrush;
716  HBRUSH brush;
717  COLORREF color;
718  POINT oldPt;
719  int width;
720  BOOL atTop = (para->pCell != para->prev_para->member.para.pCell);
721  BOOL atBottom = (para->pCell != para->next_para->member.para.pCell);
722  int top = c->pt.y + (atTop ? cell->pt.y : para->pt.y);
723  int bottom = (atBottom ?
724  c->pt.y + cell->pt.y + cell->nHeight :
725  top + para->nHeight + (atTop ? cell->yTextOffset : 0));
726  rc.left = c->pt.x + cell->pt.x;
727  rc.right = rc.left + cell->nWidth;
728  if (atTop) {
729  /* Erase gap before text if not all borders are the same height. */
730  width = max(ME_twips2pointsY(c, cell->border.top.width), 1);
731  rc.top = top + width;
732  width = cell->yTextOffset - width;
733  rc.bottom = rc.top + width;
734  if (width) {
735  FillRect(c->hDC, &rc, c->editor->hbrBackground);
736  }
737  }
738  /* Draw cell borders.
739  * The order borders are draw in is left, top, bottom, right in order
740  * to be consistent with native richedit. This is noticeable from the
741  * overlap of borders of different colours. */
742  if (!(para->nFlags & MEPF_ROWEND)) {
743  rc.top = top;
744  rc.bottom = bottom;
745  if (cell->border.left.width > 0)
746  {
747  color = cell->border.left.colorRef;
748  width = max(ME_twips2pointsX(c, cell->border.left.width), 1);
749  } else {
750  color = RGB(192,192,192);
751  width = 1;
752  }
753  logBrush.lbStyle = BS_SOLID;
754  logBrush.lbColor = color;
755  logBrush.lbHatch = 0;
757  width, &logBrush, 0, NULL);
758  oldPen = SelectObject(c->hDC, pen);
759  MoveToEx(c->hDC, rc.left, rc.top, &oldPt);
760  LineTo(c->hDC, rc.left, rc.bottom);
761  SelectObject(c->hDC, oldPen);
762  DeleteObject(pen);
763  MoveToEx(c->hDC, oldPt.x, oldPt.y, NULL);
764  }
765 
766  if (atTop) {
767  if (cell->border.top.width > 0)
768  {
769  brush = CreateSolidBrush(cell->border.top.colorRef);
770  width = max(ME_twips2pointsY(c, cell->border.top.width), 1);
771  } else {
772  brush = GetStockObject(LTGRAY_BRUSH);
773  width = 1;
774  }
775  rc.top = top;
776  rc.bottom = rc.top + width;
777  FillRect(c->hDC, &rc, brush);
778  if (cell->border.top.width > 0)
779  DeleteObject(brush);
780  }
781 
782  /* Draw the bottom border if at the last paragraph in the cell, and when
783  * in the last row of the table. */
784  if (atBottom) {
785  int oldLeft = rc.left;
786  width = max(ME_twips2pointsY(c, cell->border.bottom.width), 1);
787  paraAfterRow = ME_GetTableRowEnd(paragraph)->member.para.next_para;
788  if (paraAfterRow->member.para.nFlags & MEPF_ROWSTART) {
789  ME_DisplayItem *nextEndCell;
790  nextEndCell = ME_FindItemBack(ME_GetTableRowEnd(paraAfterRow), diCell);
791  assert(nextEndCell && !nextEndCell->member.cell.next_cell);
792  rc.left = c->pt.x + nextEndCell->member.cell.pt.x;
793  /* FIXME: Native draws FROM the bottom of the table rather than
794  * TO the bottom of the table in this case, but just doing so here
795  * will cause the next row to erase the border. */
796  /*
797  rc.top = bottom;
798  rc.bottom = rc.top + width;
799  */
800  }
801  if (rc.left < rc.right) {
802  if (cell->border.bottom.width > 0) {
803  brush = CreateSolidBrush(cell->border.bottom.colorRef);
804  } else {
805  brush = GetStockObject(LTGRAY_BRUSH);
806  }
807  rc.bottom = bottom;
808  rc.top = rc.bottom - width;
809  FillRect(c->hDC, &rc, brush);
810  if (cell->border.bottom.width > 0)
811  DeleteObject(brush);
812  }
813  rc.left = oldLeft;
814  }
815 
816  /* Right border only drawn if at the end of the table row. */
817  if (!cell->next_cell->member.cell.next_cell &&
818  !(para->nFlags & MEPF_ROWSTART))
819  {
820  rc.top = top;
821  rc.bottom = bottom;
822  if (cell->border.right.width > 0) {
823  color = cell->border.right.colorRef;
824  width = max(ME_twips2pointsX(c, cell->border.right.width), 1);
825  } else {
826  color = RGB(192,192,192);
827  width = 1;
828  }
829  logBrush.lbStyle = BS_SOLID;
830  logBrush.lbColor = color;
831  logBrush.lbHatch = 0;
833  width, &logBrush, 0, NULL);
834  oldPen = SelectObject(c->hDC, pen);
835  MoveToEx(c->hDC, rc.right - 1, rc.top, &oldPt);
836  LineTo(c->hDC, rc.right - 1, rc.bottom);
837  SelectObject(c->hDC, oldPen);
838  DeleteObject(pen);
839  MoveToEx(c->hDC, oldPt.x, oldPt.y, NULL);
840  }
841  }
842  } else { /* v1.0 - 3.0 */
843  /* Draw simple table border */
844  if (para->fmt.dwMask & PFM_TABLE && para->fmt.wEffects & PFE_TABLE) {
845  HPEN pen = NULL, oldpen = NULL;
846  int i, firstX, startX, endX, rowY, rowBottom, nHeight;
847  POINT oldPt;
848  PARAFORMAT2 *pNextFmt;
849 
850  pen = CreatePen(PS_SOLID, 0, para->border.top.colorRef);
851  oldpen = SelectObject(c->hDC, pen);
852 
853  /* Find the start relative to the text */
854  firstX = c->pt.x + ME_FindItemFwd(paragraph, diRun)->member.run.pt.x;
855  /* Go back by the horizontal gap, which is stored in dxOffset */
856  firstX -= ME_twips2pointsX(c, para->fmt.dxOffset);
857  /* The left edge, stored in dxStartIndent affected just the first edge */
858  startX = firstX - ME_twips2pointsX(c, para->fmt.dxStartIndent);
859  rowY = c->pt.y + para->pt.y;
860  if (para->fmt.dwMask & PFM_SPACEBEFORE)
861  rowY += ME_twips2pointsY(c, para->fmt.dySpaceBefore);
862  nHeight = ME_FindItemFwd(paragraph, diStartRow)->member.row.nHeight;
863  rowBottom = rowY + nHeight;
864 
865  /* Draw horizontal lines */
866  MoveToEx(c->hDC, firstX, rowY, &oldPt);
867  i = para->fmt.cTabCount - 1;
868  endX = startX + ME_twips2pointsX(c, para->fmt.rgxTabs[i] & 0x00ffffff) + 1;
869  LineTo(c->hDC, endX, rowY);
870  pNextFmt = &para->next_para->member.para.fmt;
871  /* The bottom of the row only needs to be drawn if the next row is
872  * not a table. */
873  if (!(pNextFmt && pNextFmt->dwMask & PFM_TABLE && pNextFmt->wEffects &&
874  para->nRows == 1))
875  {
876  /* Decrement rowBottom to draw the bottom line within the row, and
877  * to not draw over this line when drawing the vertical lines. */
878  rowBottom--;
879  MoveToEx(c->hDC, firstX, rowBottom, NULL);
880  LineTo(c->hDC, endX, rowBottom);
881  }
882 
883  /* Draw vertical lines */
884  MoveToEx(c->hDC, firstX, rowY, NULL);
885  LineTo(c->hDC, firstX, rowBottom);
886  for (i = 0; i < para->fmt.cTabCount; i++)
887  {
888  int rightBoundary = para->fmt.rgxTabs[i] & 0x00ffffff;
889  endX = startX + ME_twips2pointsX(c, rightBoundary);
890  MoveToEx(c->hDC, endX, rowY, NULL);
891  LineTo(c->hDC, endX, rowBottom);
892  }
893 
894  MoveToEx(c->hDC, oldPt.x, oldPt.y, NULL);
895  SelectObject(c->hDC, oldpen);
896  DeleteObject(pen);
897  }
898  }
899 }
900 
902 {
903  ME_Paragraph *para = &p->member.para;
904  HFONT old_font;
905  int x, y;
906  COLORREF old_text;
907 
908  if (para->fmt.wNumbering)
909  {
910  old_font = ME_SelectStyleFont( c, para->para_num.style );
911  old_text = SetTextColor( c->hDC, get_text_color( c, para->para_num.style, FALSE ) );
912 
913  x = c->pt.x + para->para_num.pt.x;
914  y = c->pt.y + para->pt.y + para->para_num.pt.y;
915 
916  ExtTextOutW( c->hDC, x, y, 0, NULL, para->para_num.text->szData, para->para_num.text->nLen, NULL );
917 
918  SetTextColor( c->hDC, old_text );
919  ME_UnselectStyleFont( c, para->para_num.style, old_font );
920  }
921 }
922 
923 static void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph)
924 {
925  int align = SetTextAlign(c->hDC, TA_BASELINE);
926  ME_DisplayItem *p;
927  ME_Run *run;
928  ME_Paragraph *para = NULL;
929  RECT rc, bounds;
930  int y;
931  int height = 0, baseline = 0, no=0;
932  BOOL visible = FALSE;
933 
934  rc.left = c->pt.x;
935  rc.right = c->rcView.right;
936 
937  assert(paragraph);
938  para = &paragraph->member.para;
939  y = c->pt.y + para->pt.y;
940  if (para->pCell)
941  {
942  ME_Cell *cell = &para->pCell->member.cell;
943  rc.left = c->pt.x + cell->pt.x;
944  rc.right = rc.left + cell->nWidth;
945  }
946  if (para->nFlags & MEPF_ROWSTART) {
947  ME_Cell *cell = &para->next_para->member.para.pCell->member.cell;
948  rc.right = c->pt.x + cell->pt.x;
949  } else if (para->nFlags & MEPF_ROWEND) {
950  ME_Cell *cell = &para->prev_para->member.para.pCell->member.cell;
951  rc.left = c->pt.x + cell->pt.x + cell->nWidth;
952  }
953  ME_DrawParaDecoration(c, para, y, &bounds);
954  y += bounds.top;
955  if (bounds.left || bounds.right) {
956  rc.left = max(rc.left, c->pt.x + bounds.left);
957  rc.right = min(rc.right, c->pt.x - bounds.right
958  + max(c->editor->sizeWindow.cx,
959  c->editor->nTotalWidth));
960  }
961 
962  for (p = paragraph->next; p != para->next_para; p = p->next)
963  {
964  switch(p->type) {
965  case diParagraph:
966  assert(FALSE);
967  break;
968  case diStartRow:
969  y += height;
970  rc.top = y;
971  if (para->nFlags & (MEPF_ROWSTART|MEPF_ROWEND)) {
972  rc.bottom = y + para->nHeight;
973  } else {
974  rc.bottom = y + p->member.row.nHeight;
975  }
976  visible = RectVisible(c->hDC, &rc);
977  if (visible) {
978  FillRect(c->hDC, &rc, c->editor->hbrBackground);
979  }
980  if (bounds.right)
981  {
982  /* If scrolled to the right past the end of the text, then
983  * there may be space to the right of the paragraph border. */
984  RECT rcAfterBrdr = rc;
985  rcAfterBrdr.left = rc.right + bounds.right;
986  rcAfterBrdr.right = c->rcView.right;
987  if (RectVisible(c->hDC, &rcAfterBrdr))
988  FillRect(c->hDC, &rcAfterBrdr, c->editor->hbrBackground);
989  }
990  if (me_debug)
991  {
992  static const WCHAR wszRowDebug[] = {'r','o','w','[','%','d',']',0};
993  WCHAR buf[128];
994  POINT pt = c->pt;
995  wsprintfW(buf, wszRowDebug, no);
996  pt.y = 12+y;
997  ME_DebugWrite(c->hDC, &pt, buf);
998  }
999 
1000  height = p->member.row.nHeight;
1001  baseline = p->member.row.nBaseline;
1002  break;
1003  case diRun:
1004  assert(para);
1005  run = &p->member.run;
1006  if (visible && me_debug) {
1007  RECT rc;
1008  rc.left = c->pt.x + run->pt.x;
1009  rc.right = rc.left + run->nWidth;
1010  rc.top = c->pt.y + para->pt.y + run->pt.y;
1011  rc.bottom = rc.top + height;
1012  TRACE("rc = %s\n", wine_dbgstr_rect(&rc));
1014  }
1015  if (visible)
1016  ME_DrawRun(c, c->pt.x + run->pt.x,
1017  c->pt.y + para->pt.y + run->pt.y + baseline, p, para);
1018  if (me_debug)
1019  {
1020  static const WCHAR wszRunDebug[] = {'[','%','d',':','%','x',']',' ','%','l','s',0};
1021  WCHAR buf[2560];
1022  POINT pt;
1023  pt.x = c->pt.x + run->pt.x;
1024  pt.y = c->pt.y + para->pt.y + run->pt.y;
1025  wsprintfW(buf, wszRunDebug, no, p->member.run.nFlags, get_text( &p->member.run, 0 ));
1026  ME_DebugWrite(c->hDC, &pt, buf);
1027  }
1028  break;
1029  case diCell:
1030  /* Clear any space at the bottom of the cell after the text. */
1031  if (para->nFlags & (MEPF_ROWSTART|MEPF_ROWEND))
1032  break;
1033  y += height;
1034  rc.top = c->pt.y + para->pt.y + para->nHeight;
1035  rc.bottom = c->pt.y + p->member.cell.pt.y + p->member.cell.nHeight;
1036  if (RectVisible(c->hDC, &rc))
1037  {
1038  FillRect(c->hDC, &rc, c->editor->hbrBackground);
1039  }
1040  break;
1041  default:
1042  break;
1043  }
1044  no++;
1045  }
1046 
1047  ME_DrawTableBorders(c, paragraph);
1048  draw_para_number(c, paragraph);
1049 
1050  SetTextAlign(c->hDC, align);
1051 }
1052 
1053 void ME_ScrollAbs(ME_TextEditor *editor, int x, int y)
1054 {
1055  BOOL bScrollBarIsVisible, bScrollBarWillBeVisible;
1056  int scrollX = 0, scrollY = 0;
1057 
1058  if (editor->horz_si.nPos != x) {
1059  x = min(x, editor->horz_si.nMax);
1060  x = max(x, editor->horz_si.nMin);
1061  scrollX = editor->horz_si.nPos - x;
1062  editor->horz_si.nPos = x;
1063  if (editor->horz_si.nMax > 0xFFFF) /* scale to 16-bit value */
1064  x = MulDiv(x, 0xFFFF, editor->horz_si.nMax);
1066  }
1067 
1068  if (editor->vert_si.nPos != y) {
1069  y = min(y, editor->vert_si.nMax - (int)editor->vert_si.nPage);
1070  y = max(y, editor->vert_si.nMin);
1071  scrollY = editor->vert_si.nPos - y;
1072  editor->vert_si.nPos = y;
1073  if (editor->vert_si.nMax > 0xFFFF) /* scale to 16-bit value */
1074  y = MulDiv(y, 0xFFFF, editor->vert_si.nMax);
1076  }
1077 
1078  if (abs(scrollX) > editor->sizeWindow.cx ||
1079  abs(scrollY) > editor->sizeWindow.cy)
1081  else
1082  ITextHost_TxScrollWindowEx(editor->texthost, scrollX, scrollY,
1083  &editor->rcFormat, &editor->rcFormat,
1084  NULL, NULL, SW_INVALIDATE);
1085  ME_Repaint(editor);
1086 
1087  if (editor->hWnd)
1088  {
1089  LONG winStyle = GetWindowLongW(editor->hWnd, GWL_STYLE);
1090  if (editor->styleFlags & WS_HSCROLL)
1091  {
1092  bScrollBarIsVisible = (winStyle & WS_HSCROLL) != 0;
1093  bScrollBarWillBeVisible = (editor->nTotalWidth > editor->sizeWindow.cx
1094  && (editor->styleFlags & WS_HSCROLL))
1095  || (editor->styleFlags & ES_DISABLENOSCROLL);
1096  if (bScrollBarIsVisible != bScrollBarWillBeVisible)
1098  bScrollBarWillBeVisible);
1099  }
1100 
1101  if (editor->styleFlags & WS_VSCROLL)
1102  {
1103  bScrollBarIsVisible = (winStyle & WS_VSCROLL) != 0;
1104  bScrollBarWillBeVisible = (editor->nTotalLength > editor->sizeWindow.cy
1105  && (editor->styleFlags & WS_VSCROLL)
1106  && (editor->styleFlags & ES_MULTILINE))
1107  || (editor->styleFlags & ES_DISABLENOSCROLL);
1108  if (bScrollBarIsVisible != bScrollBarWillBeVisible)
1110  bScrollBarWillBeVisible);
1111  }
1112  }
1113  ME_UpdateScrollBar(editor);
1114 }
1115 
1116 void ME_HScrollAbs(ME_TextEditor *editor, int x)
1117 {
1118  ME_ScrollAbs(editor, x, editor->vert_si.nPos);
1119 }
1120 
1121 void ME_VScrollAbs(ME_TextEditor *editor, int y)
1122 {
1123  ME_ScrollAbs(editor, editor->horz_si.nPos, y);
1124 }
1125 
1126 void ME_ScrollUp(ME_TextEditor *editor, int cy)
1127 {
1128  ME_VScrollAbs(editor, editor->vert_si.nPos - cy);
1129 }
1130 
1131 void ME_ScrollDown(ME_TextEditor *editor, int cy)
1132 {
1133  ME_VScrollAbs(editor, editor->vert_si.nPos + cy);
1134 }
1135 
1136 void ME_ScrollLeft(ME_TextEditor *editor, int cx)
1137 {
1138  ME_HScrollAbs(editor, editor->horz_si.nPos - cx);
1139 }
1140 
1141 void ME_ScrollRight(ME_TextEditor *editor, int cx)
1142 {
1143  ME_HScrollAbs(editor, editor->horz_si.nPos + cx);
1144 }
1145 
1146 /* Calculates the visibility after a call to SetScrollRange or
1147  * SetScrollInfo with SIF_RANGE. */
1149 {
1150  if (si->fMask & SIF_DISABLENOSCROLL)
1151  return TRUE;
1152 
1153  /* This must match the check in SetScrollInfo to determine whether
1154  * to show or hide the scrollbars. */
1155  return si->nMin < si->nMax - max(si->nPage - 1, 0);
1156 }
1157 
1159 {
1160  /* Note that this is the only function that should ever call
1161  * SetScrollInfo with SIF_PAGE or SIF_RANGE. */
1162 
1163  SCROLLINFO si;
1164  BOOL bScrollBarWasVisible, bScrollBarWillBeVisible;
1165 
1166  if (ME_WrapMarkedParagraphs(editor))
1167  FIXME("ME_UpdateScrollBar had to call ME_WrapMarkedParagraphs\n");
1168 
1169  si.cbSize = sizeof(si);
1170  si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS;
1171  si.nMin = 0;
1172  if (editor->styleFlags & ES_DISABLENOSCROLL)
1173  si.fMask |= SIF_DISABLENOSCROLL;
1174 
1175  /* Update horizontal scrollbar */
1176  bScrollBarWasVisible = editor->horz_si.nMax > editor->horz_si.nPage;
1177  bScrollBarWillBeVisible = editor->nTotalWidth > editor->sizeWindow.cx;
1178  if (editor->horz_si.nPos && !bScrollBarWillBeVisible)
1179  {
1180  ME_HScrollAbs(editor, 0);
1181  /* ME_HScrollAbs will call this function,
1182  * so nothing else needs to be done here. */
1183  return;
1184  }
1185 
1186  si.nMax = editor->nTotalWidth;
1187  si.nPos = editor->horz_si.nPos;
1188  si.nPage = editor->sizeWindow.cx;
1189 
1190  if (si.nMax != editor->horz_si.nMax ||
1191  si.nPage != editor->horz_si.nPage)
1192  {
1193  TRACE("min=%d max=%d page=%d\n", si.nMin, si.nMax, si.nPage);
1194  editor->horz_si.nMax = si.nMax;
1195  editor->horz_si.nPage = si.nPage;
1196  if ((bScrollBarWillBeVisible || bScrollBarWasVisible) &&
1197  editor->styleFlags & WS_HSCROLL)
1198  {
1199  if (si.nMax > 0xFFFF)
1200  {
1201  /* Native scales the scrollbar info to 16-bit external values. */
1202  si.nPos = MulDiv(si.nPos, 0xFFFF, si.nMax);
1203  si.nMax = 0xFFFF;
1204  }
1205  if (editor->hWnd) {
1206  SetScrollInfo(editor->hWnd, SB_HORZ, &si, TRUE);
1207  } else {
1210  }
1211  /* SetScrollInfo or SetScrollRange change scrollbar visibility. */
1212  bScrollBarWasVisible = ME_PostSetScrollRangeVisibility(&si);
1213  }
1214  }
1215 
1216  if (editor->styleFlags & WS_HSCROLL)
1217  {
1218  if (si.fMask & SIF_DISABLENOSCROLL) {
1219  bScrollBarWillBeVisible = TRUE;
1220  } else if (!(editor->styleFlags & WS_HSCROLL)) {
1221  bScrollBarWillBeVisible = FALSE;
1222  }
1223 
1224  if (bScrollBarWasVisible != bScrollBarWillBeVisible)
1225  ITextHost_TxShowScrollBar(editor->texthost, SB_HORZ, bScrollBarWillBeVisible);
1226  }
1227 
1228  /* Update vertical scrollbar */
1229  bScrollBarWasVisible = editor->vert_si.nMax > editor->vert_si.nPage;
1230  bScrollBarWillBeVisible = editor->nTotalLength > editor->sizeWindow.cy &&
1231  (editor->styleFlags & ES_MULTILINE);
1232 
1233  if (editor->vert_si.nPos && !bScrollBarWillBeVisible)
1234  {
1235  ME_VScrollAbs(editor, 0);
1236  /* ME_VScrollAbs will call this function,
1237  * so nothing else needs to be done here. */
1238  return;
1239  }
1240 
1241  si.nMax = editor->nTotalLength;
1242  si.nPos = editor->vert_si.nPos;
1243  si.nPage = editor->sizeWindow.cy;
1244 
1245  if (si.nMax != editor->vert_si.nMax ||
1246  si.nPage != editor->vert_si.nPage)
1247  {
1248  TRACE("min=%d max=%d page=%d\n", si.nMin, si.nMax, si.nPage);
1249  editor->vert_si.nMax = si.nMax;
1250  editor->vert_si.nPage = si.nPage;
1251  if ((bScrollBarWillBeVisible || bScrollBarWasVisible) &&
1252  editor->styleFlags & WS_VSCROLL)
1253  {
1254  if (si.nMax > 0xFFFF)
1255  {
1256  /* Native scales the scrollbar info to 16-bit external values. */
1257  si.nPos = MulDiv(si.nPos, 0xFFFF, si.nMax);
1258  si.nMax = 0xFFFF;
1259  }
1260  if (editor->hWnd) {
1261  SetScrollInfo(editor->hWnd, SB_VERT, &si, TRUE);
1262  } else {
1265  }
1266  /* SetScrollInfo or SetScrollRange change scrollbar visibility. */
1267  bScrollBarWasVisible = ME_PostSetScrollRangeVisibility(&si);
1268  }
1269  }
1270 
1271  if (editor->styleFlags & WS_VSCROLL)
1272  {
1273  if (si.fMask & SIF_DISABLENOSCROLL) {
1274  bScrollBarWillBeVisible = TRUE;
1275  } else if (!(editor->styleFlags & WS_VSCROLL)) {
1276  bScrollBarWillBeVisible = FALSE;
1277  }
1278 
1279  if (bScrollBarWasVisible != bScrollBarWillBeVisible)
1281  bScrollBarWillBeVisible);
1282  }
1283 }
1284 
1286 {
1287  ME_Run *pRun = &pCursor->pRun->member.run;
1288  ME_DisplayItem *pRow = ME_FindItemBack(pCursor->pRun, diStartRow);
1289  ME_DisplayItem *pPara = pCursor->pPara;
1290  int x, y, yheight;
1291 
1292  assert(pRow);
1293  assert(pPara);
1294 
1295  if (editor->styleFlags & ES_AUTOHSCROLL)
1296  {
1297  x = pRun->pt.x + ME_PointFromChar(editor, pRun, pCursor->nOffset, TRUE);
1298  if (x > editor->horz_si.nPos + editor->sizeWindow.cx)
1299  x = x + 1 - editor->sizeWindow.cx;
1300  else if (x > editor->horz_si.nPos)
1301  x = editor->horz_si.nPos;
1302 
1303  if (~editor->styleFlags & ES_AUTOVSCROLL)
1304  {
1305  ME_HScrollAbs(editor, x);
1306  return;
1307  }
1308  } else {
1309  if (~editor->styleFlags & ES_AUTOVSCROLL)
1310  return;
1311  x = editor->horz_si.nPos;
1312  }
1313 
1314  y = pPara->member.para.pt.y + pRow->member.row.pt.y;
1315  yheight = pRow->member.row.nHeight;
1316 
1317  if (y < editor->vert_si.nPos)
1318  ME_ScrollAbs(editor, x, y);
1319  else if (y + yheight > editor->vert_si.nPos + editor->sizeWindow.cy)
1320  ME_ScrollAbs(editor, x, y + yheight - editor->sizeWindow.cy);
1321  else if (x != editor->horz_si.nPos)
1322  ME_ScrollAbs(editor, x, editor->vert_si.nPos);
1323 }
1324 
1325 
1326 void
1328 {
1329  ME_DisplayItem *sel_start, *sel_end;
1330  ME_DisplayItem *repaint_start = NULL, *repaint_end = NULL;
1331  int nStart, nEnd;
1332  int len = ME_GetTextLength(editor);
1333 
1334  ME_GetSelectionOfs(editor, &nStart, &nEnd);
1335  /* if both old and new selection are 0-char (= caret only), then
1336  there's no (inverted) area to be repainted, neither old nor new */
1337  if (nStart == nEnd && editor->nLastSelStart == editor->nLastSelEnd)
1338  return;
1339  ME_WrapMarkedParagraphs(editor);
1340  ME_GetSelectionParas(editor, &sel_start, &sel_end);
1341  assert(sel_start->type == diParagraph);
1342  assert(sel_end->type == diParagraph);
1343  /* last selection markers aren't always updated, which means
1344  * they can point past the end of the document */
1345  if (editor->nLastSelStart > len || editor->nLastSelEnd > len) {
1346  repaint_start = ME_FindItemFwd(editor->pBuffer->pFirst, diParagraph);
1347  repaint_end = editor->pBuffer->pLast->member.para.prev_para;
1348  } else {
1349  /* if the start part of selection is being expanded or contracted... */
1350  if (nStart < editor->nLastSelStart) {
1351  repaint_start = sel_start;
1352  repaint_end = editor->pLastSelStartPara;
1353  } else if (nStart > editor->nLastSelStart) {
1354  repaint_start = editor->pLastSelStartPara;
1355  repaint_end = sel_start;
1356  }
1357 
1358  /* if the end part of selection is being contracted or expanded... */
1359  if (nEnd < editor->nLastSelEnd) {
1360  if (!repaint_start) repaint_start = sel_end;
1361  repaint_end = editor->pLastSelEndPara;
1362  } else if (nEnd > editor->nLastSelEnd) {
1363  if (!repaint_start) repaint_start = editor->pLastSelEndPara;
1364  repaint_end = sel_end;
1365  }
1366  }
1367 
1368  if (repaint_start)
1369  ME_InvalidateParagraphRange(editor, repaint_start, repaint_end);
1370  /* remember the last invalidated position */
1371  ME_GetSelectionOfs(editor, &editor->nLastSelStart, &editor->nLastSelEnd);
1372  ME_GetSelectionParas(editor, &editor->pLastSelStartPara, &editor->pLastSelEndPara);
1374  assert(editor->pLastSelEndPara->type == diParagraph);
1375 }
1376 
1377 BOOL
1378 ME_SetZoom(ME_TextEditor *editor, int numerator, int denominator)
1379 {
1380  /* TODO: Zoom images and objects */
1381 
1382  if (numerator == 0 && denominator == 0)
1383  {
1384  editor->nZoomNumerator = editor->nZoomDenominator = 0;
1385  return TRUE;
1386  }
1387  if (numerator <= 0 || denominator <= 0)
1388  return FALSE;
1389  if (numerator * 64 <= denominator || numerator / denominator >= 64)
1390  return FALSE;
1391 
1392  editor->nZoomNumerator = numerator;
1393  editor->nZoomDenominator = denominator;
1394 
1395  ME_RewrapRepaint(editor);
1396  return TRUE;
1397 }
ME_DIType type
Definition: editstr.h:260
HGDIOBJ WINAPI GetStockObject(_In_ int)
int WINAPIV wsprintfW(_Out_ LPWSTR, _In_ _Printf_format_string_ LPCWSTR,...)
static COLORREF get_text_color(ME_Context *c, ME_Style *style, BOOL highlight)
Definition: paint.c:188
int ME_twips2pointsX(const ME_Context *c, int x)
Definition: paint.c:153
#define MEPF_ROWEND
Definition: editstr.h:149
#define PFM_SPACEBEFORE
Definition: richedit.h:847
void ME_ScrollRight(ME_TextEditor *editor, int cx)
Definition: paint.c:1141
BOOL WINAPI ExtTextOutW(_In_ HDC hdc, _In_ int x, _In_ int y, _In_ UINT options, _In_opt_ const RECT *lprect, _In_reads_opt_(c) LPCWSTR lpString, _In_ UINT c, _In_reads_opt_(c) const INT *lpDx)
#define CFE_AUTOCOLOR
Definition: richedit.h:414
#define abs(i)
Definition: fconv.c:206
#define ITextHost_TxInvalidateRect(This, a, b)
Definition: editor.h:294
#define PFM_BORDER
Definition: richedit.h:851
GLint GLint GLsizei width
Definition: gl.h:1546
#define ITextHost_TxScrollWindowEx(This, a, b, c, d, e, f, g)
Definition: editor.h:301
#define max(a, b)
Definition: svc.c:63
static HPEN get_underline_pen(ME_Style *style, COLORREF color)
Definition: paint.c:219
ME_Paragraph para
Definition: editstr.h:266
#define TRUE
Definition: types.h:120
HPEN WINAPI CreatePen(_In_ int, _In_ int, _In_ COLORREF)
#define COLOR_HIGHLIGHT
Definition: winuser.h:916
void ME_ScrollAbs(ME_TextEditor *editor, int x, int y)
Definition: paint.c:1053
#define CFU_UNDERLINEWORD
Definition: richedit.h:429
#define SIF_RANGE
Definition: winuser.h:1221
ME_Border top
Definition: editstr.h:192
void ME_EnsureVisible(ME_TextEditor *editor, ME_Cursor *pCursor)
Definition: paint.c:1285
HFONT ME_SelectStyleFont(ME_Context *c, ME_Style *s) DECLSPEC_HIDDEN
Definition: style.c:356
int WINAPI SelectClipRgn(_In_ HDC, _In_opt_ HRGN)
long y
Definition: polytest.cpp:48
static const struct @510 border_details[]
WCHAR * szData
Definition: editstr.h:60
static void ME_DrawTableBorders(ME_Context *c, ME_DisplayItem *paragraph)
Definition: paint.c:704
int nZoomNumerator
Definition: editstr.h:415
#define CFM_SUBSCRIPT
Definition: richedit.h:348
#define CFE_UNDERLINE
Definition: richedit.h:408
DWORD styleFlags
Definition: editstr.h:392
BOOL WINAPI OffsetRect(_Inout_ LPRECT, _In_ int, _In_ int)
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
long x
Definition: polytest.cpp:48
UINT lbStyle
Definition: wingdi.h:1742
static void draw_space(ME_Context *c, ME_Run *run, int x, int y, BOOL selected, BOOL actually_draw, int ymin, int cy)
Definition: paint.c:269
HRESULT WINAPI ScriptTextOut(const HDC hdc, SCRIPT_CACHE *psc, int x, int y, UINT fuOptions, const RECT *lprc, const SCRIPT_ANALYSIS *psa, const WCHAR *pwcReserved, int iReserved, const WORD *pwGlyphs, int cGlyphs, const int *piAdvance, const int *piJustify, const GOFFSET *pGoffset)
Definition: usp10.c:3590
#define SB_VERT
Definition: winuser.h:553
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
BOOL ME_SetZoom(ME_TextEditor *editor, int numerator, int denominator)
Definition: paint.c:1378
#define pt(x, y)
Definition: drawing.c:79
static void draw_text(ME_Context *c, ME_Run *run, int x, int y, BOOL selected, RECT *sel_rect)
Definition: paint.c:332
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
const WCHAR * text
Definition: package.c:1827
ULONG_PTR lbHatch
Definition: wingdi.h:1744
#define SB_HORZ
Definition: winuser.h:552
#define CFU_UNDERLINE
Definition: richedit.h:428
struct tagME_DisplayItem * pCell
Definition: editstr.h:211
#define ES_MULTILINE
Definition: pedump.c:667
unsigned pen_style
Definition: paint.c:495
HRGN WINAPI CreateRectRgnIndirect(_In_ LPCRECT)
static HDC
Definition: imagelist.c:92
#define MERF_GRAPHICS
Definition: editstr.h:109
#define CFE_SUBSCRIPT
Definition: richedit.h:412
#define PFM_SPACEAFTER
Definition: richedit.h:848
WINE_DEFAULT_DEBUG_CHANNEL(richedit)
struct tagME_Paragraph * para
Definition: editstr.h:165
LONG top
Definition: windef.h:292
static int ME_GetBorderPenWidth(const ME_Context *c, int idx)
Definition: paint.c:521
unsigned dble
Definition: paint.c:495
int WINAPI IntersectClipRect(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int)
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1497
#define CFM_SUPERSCRIPT
Definition: richedit.h:349
#define assert(x)
Definition: debug.h:53
BOOL WINAPI DeleteObject(_In_ HGDIOBJ)
BOOL WINAPI LineTo(_In_ HDC, _In_ int, _In_ int)
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
#define CFE_LINK
Definition: richedit.h:411
int ME_GetSelectionOfs(ME_TextEditor *editor, int *from, int *to)
Definition: caret.c:42
struct tagME_DisplayItem * prev_para
Definition: editstr.h:221
#define ITextHost_TxGetSysColor(This, a)
Definition: editor.h:313
SHORT cTabCount
Definition: richedit.h:674
POINT pt
Definition: editstr.h:230
#define PS_JOIN_MITER
Definition: wingdi.h:597
#define TA_LEFT
Definition: wingdi.h:931
void ME_UnselectStyleFont(ME_Context *c, ME_Style *s, HFONT hOldFont) DECLSPEC_HIDDEN
Definition: style.c:416
ME_DisplayItem * ME_GetTableRowEnd(ME_DisplayItem *para) DECLSPEC_HIDDEN
Definition: table.c:136
int align(int length, int align)
Definition: dsound8.c:36
LONG left
Definition: windef.h:291
static void draw_para_number(ME_Context *c, ME_DisplayItem *p)
Definition: paint.c:901
UINT WINAPI SetTextAlign(_In_ HDC, _In_ UINT)
Definition: text.c:853
int ME_PointFromChar(ME_TextEditor *editor, ME_Run *pRun, int nOffset, BOOL visual_order) DECLSPEC_HIDDEN
Definition: run.c:599
int nCharOfs
Definition: editstr.h:166
ME_Style * style
Definition: editstr.h:164
LONG right
Definition: windef.h:293
#define PS_GEOMETRIC
Definition: wingdi.h:582
#define lstrlenW
Definition: compat.h:407
void ME_SendRequestResize(ME_TextEditor *editor, BOOL force) DECLSPEC_HIDDEN
Definition: wrap.c:1201
#define COLOR_WINDOW
Definition: winuser.h:908
#define SIF_PAGE
Definition: winuser.h:1219
static void ME_DebugWrite(HDC hDC, const POINT *pt, LPCWSTR szText)
Definition: paint.c:438
& rect
Definition: startmenu.cpp:1413
ME_DisplayItem * pLastSelStartPara
Definition: editstr.h:413
HFONT hFont
Definition: main.c:53
LONG dySpaceAfter
Definition: richedit.h:676
static void get_selection_rect(ME_Context *c, ME_Run *run, int from, int to, int cy, RECT *r)
Definition: paint.c:321
SCROLLINFO vert_si
Definition: editstr.h:443
LONG rgxTabs[MAX_TAB_STOPS]
Definition: richedit.h:675
#define MERF_TAB
Definition: editstr.h:111
#define RGN_AND
Definition: wingdi.h:355
COLORREF WINAPI SetBkColor(_In_ HDC, _In_ COLORREF)
Definition: dc.c:975
WORD wNumbering
Definition: richedit.h:668
BOOL WINAPI PatBlt(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int, _In_ DWORD)
BOOL WINAPI MoveToEx(_In_ HDC, _In_ int, _In_ int, _Out_opt_ LPPOINT)
static void draw_underline(ME_Context *c, ME_Run *run, int x, int y, COLORREF color)
Definition: paint.c:246
#define CFU_UNDERLINENONE
Definition: richedit.h:427
#define PS_SOLID
Definition: wingdi.h:585
int WINAPI ExtSelectClipRgn(_In_ HDC, _In_opt_ HRGN, _In_ int)
#define TA_TOP
Definition: wingdi.h:929
int WINAPI SetBkMode(_In_ HDC, _In_ int)
Definition: dc.c:1032
ME_DisplayItem * pFirst
Definition: editstr.h:272
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
struct tagME_DisplayItem * next
Definition: editstr.h:261
#define ETO_OPAQUE
Definition: wingdi.h:646
#define MERF_HIDDEN
Definition: editstr.h:130
static const WCHAR szText[]
Definition: dialog.c:139
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
GLuint color
Definition: glext.h:6243
static COLORREF get_back_color(ME_Context *c, ME_Style *style, BOOL highlight)
Definition: paint.c:204
#define TA_BASELINE
Definition: wingdi.h:927
static char selected[MAX_PATH+1]
Definition: dirdlg.c:7
POINT pt
Definition: editstr.h:243
#define FIXME(fmt,...)
Definition: debug.h:110
static void ME_DrawParaDecoration(ME_Context *c, ME_Paragraph *para, int y, RECT *bounds)
Definition: paint.c:549
unsigned int idx
Definition: utils.c:41
#define TRANSPARENT
Definition: wingdi.h:949
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:570
BOOL WINAPI IsRectEmpty(_In_ LPCRECT)
#define MERF_ENDPARA
Definition: editstr.h:126
ME_TextBuffer * pBuffer
Definition: editstr.h:390
LONG dxStartIndent
Definition: richedit.h:670
LONG WINAPI GetWindowLongW(_In_ HWND, _In_ int)
#define CFM_COLOR
Definition: richedit.h:361
smooth NULL
Definition: ftsmooth.c:416
DWORD dwEffects
Definition: richedit.h:307
Definition: editstr.h:91
LONG cx
Definition: windef.h:319
int len
Definition: editstr.h:167
void ME_InitContext(ME_Context *c, ME_TextEditor *editor, HDC hDC)
Definition: context.c:23
#define LTGRAY_BRUSH
Definition: wingdi.h:899
GLint GLint bottom
Definition: glext.h:7726
#define CFE_SUPERSCRIPT
Definition: richedit.h:413
#define COLOR_HIGHLIGHTTEXT
Definition: winuser.h:917
#define PFE_TABLE
Definition: richedit.h:944
void ME_UpdateScrollBar(ME_TextEditor *editor)
Definition: paint.c:1158
DWORD dwMask
Definition: richedit.h:667
#define CFU_UNDERLINEDOUBLE
Definition: richedit.h:430
#define CFE_AUTOBACKCOLOR
Definition: richedit.h:425
ME_DisplayItem * pLastSelEndPara
Definition: editstr.h:413
#define DSTINVERT
Definition: wingdi.h:326
HRGN WINAPI CreateRectRgn(_In_ int, _In_ int, _In_ int, _In_ int)
ME_BorderRect border
Definition: editstr.h:212
#define ES_AUTOVSCROLL
Definition: pedump.c:671
void ME_PaintContent(ME_TextEditor *editor, HDC hDC, const RECT *rcUpdate)
Definition: paint.c:28
void ME_GetSelectionParas(ME_TextEditor *editor, ME_DisplayItem **para, ME_DisplayItem **para_end) DECLSPEC_HIDDEN
Definition: para.c:884
#define TRACE(s)
Definition: solgame.cpp:4
BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) DECLSPEC_HIDDEN
Definition: wrap.c:1096
static WCHAR no[MAX_STRING_RESOURCE_LEN]
Definition: object.c:2340
#define CFU_CF1UNDERLINE
Definition: richedit.h:447
void ME_VScrollAbs(ME_TextEditor *editor, int y)
Definition: paint.c:1121
__wchar_t WCHAR
Definition: xmlstorage.h:180
GOFFSET * offsets
Definition: editstr.h:179
void ME_SendSelChange(ME_TextEditor *editor)
Definition: caret.c:1541
DWORD COLORREF
Definition: windef.h:285
#define COLOR_WINDOWTEXT
Definition: winuser.h:911
void ME_RewrapRepaint(ME_TextEditor *editor)
Definition: paint.c:142
#define RGB(r, g, b)
Definition: wingdi.h:2935
COLORREF lbColor
Definition: wingdi.h:1743
const GLubyte * c
Definition: glext.h:8905
const char * wine_dbgstr_rect(const RECT *rect)
union tagME_DisplayItem::@508 member
void ME_SendOldNotify(ME_TextEditor *editor, int nCode)
Definition: editor.c:5100
void ME_InvalidateSelection(ME_TextEditor *editor)
Definition: paint.c:1327
void ME_ScrollUp(ME_TextEditor *editor, int cy)
Definition: paint.c:1126
ME_String * ME_MakeStringR(WCHAR cRepeat, int nMaxChars) DECLSPEC_HIDDEN
Definition: string.c:85
ME_DisplayItem * pPara
Definition: editstr.h:279
#define CFM_OFFSET
Definition: richedit.h:359
void ME_DestroyContext(ME_Context *c)
Definition: context.c:42
#define ES_NOHIDESEL
Definition: pedump.c:673
#define WS_HSCROLL
Definition: pedump.c:628
GLbitfield flags
Definition: glext.h:7161
#define DEFAULT_GUI_FONT
Definition: wingdi.h:908
int nFlags
Definition: editstr.h:169
ME_BorderRect border
Definition: editstr.h:229
#define MEPF_ROWSTART
Definition: editstr.h:148
#define COLOR_GRAYTEXT
Definition: winuser.h:922
ITextHost * texthost
Definition: editstr.h:387
#define PFM_TABLE
Definition: richedit.h:870
#define ENM_CHANGE
Definition: richedit.h:468
#define ES_DISABLENOSCROLL
Definition: richedit.h:224
HDC hdc
Definition: main.c:9
int nWidth
Definition: editstr.h:168
int nOffset
Definition: editstr.h:281
#define MERF_ENDCELL
Definition: editstr.h:113
GLenum GLsizei len
Definition: glext.h:6722
Definition: editstr.h:90
static WCHAR * get_text(const ME_Run *run, int offset)
Definition: editor.h:42
ME_DisplayItem * pLast
Definition: editstr.h:272
BOOL WINAPI SetRectEmpty(_Out_ LPRECT)
#define CFM_LINK
Definition: richedit.h:337
POINT pt
Definition: editstr.h:171
void ME_MarkAllForWrapping(ME_TextEditor *editor) DECLSPEC_HIDDEN
Definition: para.c:236
SCRIPT_CACHE script_cache
Definition: editstr.h:82
#define PS_DASH
Definition: wingdi.h:586
BOOL WINAPI IntersectRect(_Out_ LPRECT, _In_ LPCRECT, _In_ LPCRECT)
BOOL WINAPI TextOutW(_In_ HDC hdc, _In_ int x, _In_ int y, _In_reads_(c) LPCWSTR lpString, _In_ int c)
ME_Cell cell
Definition: editstr.h:265
void ME_ScrollDown(ME_TextEditor *editor, int cy)
Definition: paint.c:1131
void ME_DestroyString(ME_String *s) DECLSPEC_HIDDEN
Definition: string.c:96
#define SW_INVALIDATE
Definition: winuser.h:2554
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
#define SIF_POS
Definition: winuser.h:1220
#define RGN_COPY
Definition: wingdi.h:356
void ME_InvalidateParagraphRange(ME_TextEditor *editor, ME_DisplayItem *start_para, ME_DisplayItem *last_para) DECLSPEC_HIDDEN
Definition: wrap.c:1171
static void ME_DrawRun(ME_Context *c, int x, int y, ME_DisplayItem *rundi, ME_Paragraph *para)
Definition: paint.c:448
int * advances
Definition: editstr.h:178
WORD wEffects
Definition: richedit.h:669
void ME_HScrollAbs(ME_TextEditor *editor, int x)
Definition: paint.c:1116
#define GWL_STYLE
Definition: winuser.h:846
COLORREF WINAPI SetTextColor(_In_ HDC, _In_ COLORREF)
Definition: text.c:888
static HDC hDC
Definition: 3dtext.c:33
#define ITextHost_TxShowScrollBar(This, a, b)
Definition: editor.h:290
COLORREF colorRef
Definition: editstr.h:187
ME_Border right
Definition: editstr.h:195
unsigned width
Definition: paint.c:495
BOOL WINAPI SetRect(_Out_ LPRECT, _In_ int, _In_ int, _In_ int, _In_ int)
ME_Border bottom
Definition: editstr.h:194
static ATOM item
Definition: dde.c:856
ME_Cursor * pCursors
Definition: editstr.h:391
#define RGN_DIFF
Definition: wingdi.h:357
#define DD(x)
static void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph)
Definition: paint.c:923
PARAFORMAT2 fmt
Definition: editstr.h:208
struct para_num para_num
Definition: editstr.h:219
BOOL WINAPI RectVisible(_In_ HDC, _In_ LPCRECT)
GLuint start
Definition: gl.h:1545
#define ARRAY_SIZE(a)
Definition: main.h:24
static int calc_y_offset(const ME_Context *c, ME_Style *style)
Definition: paint.c:170
WORD wBorders
Definition: richedit.h:681
SCROLLINFO horz_si
Definition: editstr.h:443
int ME_GetParaBorderWidth(const ME_Context *c, int flags)
Definition: paint.c:534
int num_glyphs
Definition: editstr.h:175
int nHeight
Definition: editstr.h:231
#define PS_ENDCAP_FLAT
Definition: wingdi.h:595
int nLastTotalLength
Definition: editstr.h:396
DWORD dwMask
Definition: richedit.h:306
#define min(a, b)
Definition: monoChain.cc:55
int yTextOffset
Definition: editstr.h:232
struct tagME_DisplayItem * next_para
Definition: editstr.h:221
HBRUSH WINAPI CreateSolidBrush(_In_ COLORREF)
#define WS_VSCROLL
Definition: pedump.c:627
LONG dySpaceBefore
Definition: richedit.h:676
ME_DisplayItem * pRun
Definition: editstr.h:280
#define CFU_UNDERLINEDOTTED
Definition: richedit.h:431
static const COLORREF pen_colors[16]
Definition: paint.c:510
SCRIPT_ANALYSIS script_analysis
Definition: editstr.h:174
#define ITextHost_TxSetScrollPos(This, a, b, c)
Definition: editor.h:293
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
WORD * glyphs
Definition: editstr.h:176
void ME_ScrollLeft(ME_TextEditor *editor, int cx)
Definition: paint.c:1136
static DWORD *static HFONT(WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDVA *)
#define CFM_BACKCOLOR
Definition: richedit.h:357
#define PS_DOT
Definition: wingdi.h:587
static BOOL ME_PostSetScrollRangeVisibility(SCROLLINFO *si)
Definition: paint.c:1148
#define SIF_DISABLENOSCROLL
Definition: winuser.h:1222
_Out_opt_ int * cx
Definition: commctrl.h:570
struct tagME_DisplayItem * next_cell
Definition: editstr.h:233
ME_Border left
Definition: editstr.h:193
int nWidth
Definition: editstr.h:231
BOOL me_debug
Definition: editor.c:256
#define c
Definition: ke_i.h:80
#define MEPF_COMPLEX
Definition: editstr.h:150
ME_DisplayItem * ME_FindItemFwd(ME_DisplayItem *di, ME_DIType nTypeOrClass) DECLSPEC_HIDDEN
Definition: list.c:134
LONG bottom
Definition: windef.h:294
int ME_PointFromCharContext(ME_Context *c, ME_Run *pRun, int nOffset, BOOL visual_order) DECLSPEC_HIDDEN
Definition: run.c:558
void ME_DrawOLE(ME_Context *c, int x, int y, ME_Run *run, BOOL selected) DECLSPEC_HIDDEN
Definition: richole.c:5809
HPEN WINAPI ExtCreatePen(_In_ DWORD iPenStyle, _In_ DWORD cWidth, _In_ const LOGBRUSH *plbrush, _In_ DWORD cStyle, _In_reads_opt_(cStyle) const DWORD *pstyle)
#define ITextHost_TxSetScrollRange(This, a, b, c, d)
Definition: editor.h:292
int WINAPI GetClipRgn(_In_ HDC, _In_ HRGN)
static void ME_DrawTextWithStyle(ME_Context *c, ME_Run *run, int x, int y, int nSelFrom, int nSelTo, int ymin, int cy)
Definition: paint.c:370
#define BS_SOLID
Definition: wingdi.h:1085
int yOffset
Definition: appswitch.c:59
#define ITextHost_TxViewChange(This, a)
Definition: editor.h:295
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
GLfloat GLfloat p
Definition: glext.h:8902
CardRegion * from
Definition: spigame.cpp:19
int WINAPI FillRect(HDC, LPCRECT, HBRUSH)
LONG dxOffset
Definition: richedit.h:672
int nLastTotalWidth
Definition: editstr.h:397
Arabic default style
Definition: afstyles.h:93
HBRUSH WINAPI GetSysColorBrush(_In_ int)
void ME_Repaint(ME_TextEditor *editor)
Definition: paint.c:106
LONG cy
Definition: windef.h:320
CHARFORMAT2W fmt
Definition: editstr.h:77
#define ES_AUTOHSCROLL
Definition: pedump.c:672
int nZoomDenominator
Definition: editstr.h:415
int WINAPI SetScrollInfo(_In_ HWND, _In_ int, _In_ LPCSCROLLINFO, _In_ BOOL)
#define MulDiv(x, y, z)
Definition: gdifloat.h:86
void ME_MoveCaret(ME_TextEditor *editor)
Definition: caret.c:271
int ME_twips2pointsY(const ME_Context *c, int y)
Definition: paint.c:161
int ME_GetTextLength(ME_TextEditor *editor)
Definition: caret.c:83
ME_DisplayItem * ME_FindItemBack(ME_DisplayItem *di, ME_DIType nTypeOrClass) DECLSPEC_HIDDEN
Definition: list.c:111
int WINAPI FrameRect(_In_ HDC, _In_ LPCRECT, _In_ HBRUSH)
int nHeight
Definition: editstr.h:238
void ME_UpdateRepaint(ME_TextEditor *editor, BOOL update_now)
Definition: paint.c:116
#define EN_CHANGE
Definition: winuser.h:2004