ReactOS  0.4.14-dev-593-g1793dcc
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 
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  PatBlt(hDC, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY);
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  int y_offset = calc_y_offset( c, run->style );
295  static const WCHAR space[1] = {' '};
296 
297  select_style( c, run->style );
298  old_text = SetTextColor( hdc, text_color );
299  if (selected) old_back = SetBkColor( hdc, back_color );
300 
301  ExtTextOutW( hdc, x, y - y_offset, selected ? ETO_OPAQUE : 0, &rect, space, 1, &run->nWidth );
302 
303  if (selected) SetBkColor( hdc, old_back );
304  SetTextColor( hdc, old_text );
305 
306  draw_underline( c, run, x, y - y_offset, text_color );
307  }
308  else if (selected)
309  {
310  HBRUSH brush = CreateSolidBrush( back_color );
311  FillRect( hdc, &rect, brush );
312  DeleteObject( brush );
313  }
314 
315  if (old_style_selected)
316  PatBlt( hdc, x, ymin, run->nWidth, cy, DSTINVERT );
317 }
318 
319 static void get_selection_rect( ME_Context *c, ME_Run *run, int from, int to, int cy, RECT *r )
320 {
321  from = max( 0, from );
322  to = min( run->len, to );
323  r->left = ME_PointFromCharContext( c, run, from, TRUE );
324  r->top = 0;
325  r->right = ME_PointFromCharContext( c, run, to, TRUE );
326  r->bottom = cy;
327  return;
328 }
329 
330 static void draw_text( ME_Context *c, ME_Run *run, int x, int y, BOOL selected, RECT *sel_rect )
331 {
332  COLORREF text_color = get_text_color( c, run->style, selected );
333  COLORREF back_color = get_back_color( c, run->style, selected );
334  COLORREF old_text, old_back = 0;
335  const WCHAR *text = get_text( run, 0 );
336  ME_String *masked = NULL;
337  const BOOL paint_bg = ( selected
338  || ( ( run->style->fmt.dwMask & CFM_BACKCOLOR )
339  && !(CFE_AUTOBACKCOLOR & run->style->fmt.dwEffects) )
340  );
341 
342  if (c->editor->cPasswordMask)
343  {
344  masked = ME_MakeStringR( c->editor->cPasswordMask, run->len );
345  text = masked->szData;
346  }
347 
348  old_text = SetTextColor( c->hDC, text_color );
349  if (paint_bg) old_back = SetBkColor( c->hDC, back_color );
350 
351  if (run->para->nFlags & MEPF_COMPLEX)
352  ScriptTextOut( c->hDC, &run->style->script_cache, x, y, paint_bg ? ETO_OPAQUE : 0, sel_rect,
353  &run->script_analysis, NULL, 0, run->glyphs, run->num_glyphs, run->advances,
354  NULL, run->offsets );
355  else
356  ExtTextOutW( c->hDC, x, y, paint_bg ? ETO_OPAQUE : 0, sel_rect, text, run->len, NULL );
357 
358  if (paint_bg) SetBkColor( c->hDC, old_back );
359  SetTextColor( c->hDC, old_text );
360 
361  draw_underline( c, run, x, y, text_color );
362 
363  ME_DestroyString( masked );
364  return;
365 }
366 
367 
368 static void ME_DrawTextWithStyle(ME_Context *c, ME_Run *run, int x, int y,
369  int nSelFrom, int nSelTo, int ymin, int cy)
370 {
371  HDC hDC = c->hDC;
372  int yOffset = 0;
373  BOOL selected = (nSelFrom < run->len && nSelTo >= 0
374  && nSelFrom < nSelTo && !c->editor->bHideSelection &&
375  (c->editor->bHaveFocus || (c->editor->styleFlags & ES_NOHIDESEL)));
376  BOOL old_style_selected = FALSE;
377  RECT sel_rect;
378  HRGN clip = NULL, sel_rgn = NULL;
379 
380  yOffset = calc_y_offset( c, run->style );
381 
382  if (selected)
383  {
384  get_selection_rect( c, run, nSelFrom, nSelTo, cy, &sel_rect );
385  OffsetRect( &sel_rect, x, ymin );
386 
387  if (c->editor->bEmulateVersion10)
388  {
389  old_style_selected = TRUE;
390  selected = FALSE;
391  }
392  else
393  {
394  sel_rgn = CreateRectRgnIndirect( &sel_rect );
395  clip = CreateRectRgn( 0, 0, 0, 0 );
396  if (GetClipRgn( hDC, clip ) != 1)
397  {
398  DeleteObject( clip );
399  clip = NULL;
400  }
401  }
402  }
403 
404  select_style( c, run->style );
405 
406  if (sel_rgn) ExtSelectClipRgn( hDC, sel_rgn, RGN_DIFF );
407 
408  if (!(run->style->fmt.dwEffects & CFE_AUTOBACKCOLOR)
409  && (run->style->fmt.dwMask & CFM_BACKCOLOR) )
410  {
411  RECT tmp_rect;
412  get_selection_rect( c, run, 0, run->len, cy, &tmp_rect );
413  OffsetRect( &tmp_rect, x, ymin );
414  draw_text( c, run, x, y - yOffset, FALSE, &tmp_rect );
415  }
416  else
417  draw_text( c, run, x, y - yOffset, FALSE, NULL );
418 
419  if (sel_rgn)
420  {
421  ExtSelectClipRgn( hDC, clip, RGN_COPY );
422  ExtSelectClipRgn( hDC, sel_rgn, RGN_AND );
423  draw_text( c, run, x, y - yOffset, TRUE, &sel_rect );
424  ExtSelectClipRgn( hDC, clip, RGN_COPY );
425  if (clip) DeleteObject( clip );
426  DeleteObject( sel_rgn );
427  }
428 
429  if (old_style_selected)
430  PatBlt( hDC, sel_rect.left, ymin, sel_rect.right - sel_rect.left, cy, DSTINVERT );
431 }
432 
433 static void ME_DebugWrite(HDC hDC, const POINT *pt, LPCWSTR szText) {
436  COLORREF color = SetTextColor(hDC, RGB(128,128,128));
437  TextOutW(hDC, pt->x, pt->y, szText, lstrlenW(szText));
441 }
442 
443 static void ME_DrawRun(ME_Context *c, int x, int y, ME_DisplayItem *rundi, ME_Paragraph *para)
444 {
445  ME_Run *run = &rundi->member.run;
447  int runofs = run->nCharOfs+para->nCharOfs;
448  int nSelFrom, nSelTo;
449 
450  if (run->nFlags & MERF_HIDDEN)
451  return;
452 
453  start = ME_FindItemBack(rundi, diStartRow);
454  ME_GetSelectionOfs(c->editor, &nSelFrom, &nSelTo);
455 
456  /* Draw selected end-of-paragraph mark */
457  if (run->nFlags & MERF_ENDPARA)
458  {
459  if (runofs >= nSelFrom && runofs < nSelTo)
460  {
461  draw_space( c, run, x, y, TRUE, FALSE,
462  c->pt.y + para->pt.y + start->member.row.pt.y,
463  start->member.row.nHeight );
464  }
465  return;
466  }
467 
468  if (run->nFlags & (MERF_TAB | MERF_ENDCELL))
469  {
470  BOOL selected = runofs >= nSelFrom && runofs < nSelTo;
471 
472  draw_space( c, run, x, y, selected, TRUE,
473  c->pt.y + para->pt.y + start->member.row.pt.y,
474  start->member.row.nHeight );
475  return;
476  }
477 
478  if (run->nFlags & MERF_GRAPHICS)
479  ME_DrawOLE(c, x, y, run, (runofs >= nSelFrom) && (runofs < nSelTo));
480  else
481  {
482  ME_DrawTextWithStyle(c, run, x, y, nSelFrom - runofs, nSelTo - runofs,
483  c->pt.y + para->pt.y + start->member.row.pt.y,
484  start->member.row.nHeight);
485  }
486 }
487 
488 /* The documented widths are in points (72 dpi), but converting them to
489  * 96 dpi (standard display resolution) avoids dealing with fractions. */
490 static const struct {unsigned width : 8, pen_style : 4, dble : 1;} border_details[] = {
491  /* none */ {0, PS_SOLID, FALSE},
492  /* 3/4 */ {1, PS_SOLID, FALSE},
493  /* 1 1/2 */ {2, PS_SOLID, FALSE},
494  /* 2 1/4 */ {3, PS_SOLID, FALSE},
495  /* 3 */ {4, PS_SOLID, FALSE},
496  /* 4 1/2 */ {6, PS_SOLID, FALSE},
497  /* 6 */ {8, PS_SOLID, FALSE},
498  /* 3/4 double */ {1, PS_SOLID, TRUE},
499  /* 1 1/2 double */ {2, PS_SOLID, TRUE},
500  /* 2 1/4 double */ {3, PS_SOLID, TRUE},
501  /* 3/4 gray */ {1, PS_DOT /* FIXME */, FALSE},
502  /* 1 1/2 dashed */ {2, PS_DASH, FALSE},
503 };
504 
505 static const COLORREF pen_colors[16] = {
506  /* Black */ RGB(0x00, 0x00, 0x00), /* Blue */ RGB(0x00, 0x00, 0xFF),
507  /* Cyan */ RGB(0x00, 0xFF, 0xFF), /* Green */ RGB(0x00, 0xFF, 0x00),
508  /* Magenta */ RGB(0xFF, 0x00, 0xFF), /* Red */ RGB(0xFF, 0x00, 0x00),
509  /* Yellow */ RGB(0xFF, 0xFF, 0x00), /* White */ RGB(0xFF, 0xFF, 0xFF),
510  /* Dark blue */ RGB(0x00, 0x00, 0x80), /* Dark cyan */ RGB(0x00, 0x80, 0x80),
511  /* Dark green */ RGB(0x00, 0x80, 0x80), /* Dark magenta */ RGB(0x80, 0x00, 0x80),
512  /* Dark red */ RGB(0x80, 0x00, 0x00), /* Dark yellow */ RGB(0x80, 0x80, 0x00),
513  /* Dark gray */ RGB(0x80, 0x80, 0x80), /* Light gray */ RGB(0xc0, 0xc0, 0xc0),
514 };
515 
516 static int ME_GetBorderPenWidth(const ME_Context* c, int idx)
517 {
518  int width = border_details[idx].width;
519 
520  if (c->dpi.cx != 96)
521  width = MulDiv(width, c->dpi.cx, 96);
522 
523  if (c->editor->nZoomNumerator != 0)
524  width = MulDiv(width, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
525 
526  return width;
527 }
528 
530 {
531  int idx = (flags >> 8) & 0xF;
532  int width;
533 
534  if (idx >= ARRAY_SIZE(border_details))
535  {
536  FIXME("Unsupported border value %d\n", idx);
537  return 0;
538  }
540  if (border_details[idx].dble) width = width * 2 + 1;
541  return width;
542 }
543 
544 static void ME_DrawParaDecoration(ME_Context* c, ME_Paragraph* para, int y, RECT* bounds)
545 {
546  int idx, border_width, top_border, bottom_border;
547  RECT rc;
548  BOOL hasParaBorder;
549 
550  SetRectEmpty(bounds);
551  if (!(para->fmt.dwMask & (PFM_BORDER | PFM_SPACEBEFORE | PFM_SPACEAFTER))) return;
552 
553  border_width = top_border = bottom_border = 0;
554  idx = (para->fmt.wBorders >> 8) & 0xF;
555  hasParaBorder = (!(c->editor->bEmulateVersion10 &&
556  para->fmt.dwMask & PFM_TABLE &&
557  para->fmt.wEffects & PFE_TABLE) &&
558  (para->fmt.dwMask & PFM_BORDER) &&
559  idx != 0 &&
560  (para->fmt.wBorders & 0xF));
561  if (hasParaBorder)
562  {
563  /* FIXME: wBorders is not stored as MSDN says in v1.0 - 4.1 of richedit
564  * controls. It actually stores the paragraph or row border style. Although
565  * the value isn't used for drawing, it is used for streaming out rich text.
566  *
567  * wBorders stores the border style for each side (top, left, bottom, right)
568  * using nibble (4 bits) to store each border style. The rich text format
569  * control words, and their associated value are the following:
570  * \brdrdash 0
571  * \brdrdashsm 1
572  * \brdrdb 2
573  * \brdrdot 3
574  * \brdrhair 4
575  * \brdrs 5
576  * \brdrth 6
577  * \brdrtriple 7
578  *
579  * The order of the sides stored actually differs from v1.0 to 3.0 and v4.1.
580  * The mask corresponding to each side for the version are the following:
581  * mask v1.0-3.0 v4.1
582  * 0x000F top left
583  * 0x00F0 left top
584  * 0x0F00 bottom right
585  * 0xF000 right bottom
586  */
587  if (para->fmt.wBorders & 0x00B0)
588  FIXME("Unsupported border flags %x\n", para->fmt.wBorders);
589  border_width = ME_GetParaBorderWidth(c, para->fmt.wBorders);
590  if (para->fmt.wBorders & 4) top_border = border_width;
591  if (para->fmt.wBorders & 8) bottom_border = border_width;
592  }
593 
594  if (para->fmt.dwMask & PFM_SPACEBEFORE)
595  {
596  rc.left = c->rcView.left;
597  rc.right = c->rcView.right;
598  rc.top = y;
599  bounds->top = ME_twips2pointsY(c, para->fmt.dySpaceBefore);
600  rc.bottom = y + bounds->top + top_border;
601  PatBlt(c->hDC, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY);
602  }
603 
604  if (para->fmt.dwMask & PFM_SPACEAFTER)
605  {
606  rc.left = c->rcView.left;
607  rc.right = c->rcView.right;
608  rc.bottom = y + para->nHeight;
609  bounds->bottom = ME_twips2pointsY(c, para->fmt.dySpaceAfter);
610  rc.top = rc.bottom - bounds->bottom - bottom_border;
611  PatBlt(c->hDC, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY);
612  }
613 
614  /* Native richedit doesn't support paragraph borders in v1.0 - 4.1,
615  * but might support it in later versions. */
616  if (hasParaBorder) {
617  int pen_width, rightEdge;
618  COLORREF pencr;
619  HPEN pen = NULL, oldpen = NULL;
620  POINT pt;
621 
622  if (para->fmt.wBorders & 64) /* autocolor */
623  pencr = ITextHost_TxGetSysColor(c->editor->texthost,
625  else
626  pencr = pen_colors[(para->fmt.wBorders >> 12) & 0xF];
627 
628  rightEdge = c->pt.x + max(c->editor->sizeWindow.cx,
629  c->editor->nTotalWidth);
630 
631  pen_width = ME_GetBorderPenWidth(c, idx);
632  pen = CreatePen(border_details[idx].pen_style, pen_width, pencr);
633  oldpen = SelectObject(c->hDC, pen);
634  MoveToEx(c->hDC, 0, 0, &pt);
635 
636  /* before & after spaces are not included in border */
637 
638  /* helper to draw the double lines in case of corner */
639 #define DD(x) ((para->fmt.wBorders & (x)) ? (pen_width + 1) : 0)
640 
641  if (para->fmt.wBorders & 1)
642  {
643  MoveToEx(c->hDC, c->pt.x, y + bounds->top, NULL);
644  LineTo(c->hDC, c->pt.x, y + para->nHeight - bounds->bottom);
645  if (border_details[idx].dble) {
646  rc.left = c->pt.x + 1;
647  rc.right = rc.left + border_width;
648  rc.top = y + bounds->top;
649  rc.bottom = y + para->nHeight - bounds->bottom;
650  PatBlt(c->hDC, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY);
651  MoveToEx(c->hDC, c->pt.x + pen_width + 1, y + bounds->top + DD(4), NULL);
652  LineTo(c->hDC, c->pt.x + pen_width + 1, y + para->nHeight - bounds->bottom - DD(8));
653  }
654  bounds->left += border_width;
655  }
656  if (para->fmt.wBorders & 2)
657  {
658  MoveToEx(c->hDC, rightEdge - 1, y + bounds->top, NULL);
659  LineTo(c->hDC, rightEdge - 1, y + para->nHeight - bounds->bottom);
660  if (border_details[idx].dble) {
661  rc.left = rightEdge - pen_width - 1;
662  rc.right = rc.left + pen_width;
663  rc.top = y + bounds->top;
664  rc.bottom = y + para->nHeight - bounds->bottom;
665  PatBlt(c->hDC, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY);
666  MoveToEx(c->hDC, rightEdge - 1 - pen_width - 1, y + bounds->top + DD(4), NULL);
667  LineTo(c->hDC, rightEdge - 1 - pen_width - 1, y + para->nHeight - bounds->bottom - DD(8));
668  }
669  bounds->right += border_width;
670  }
671  if (para->fmt.wBorders & 4)
672  {
673  MoveToEx(c->hDC, c->pt.x, y + bounds->top, NULL);
674  LineTo(c->hDC, rightEdge, y + bounds->top);
675  if (border_details[idx].dble) {
676  MoveToEx(c->hDC, c->pt.x + DD(1), y + bounds->top + pen_width + 1, NULL);
677  LineTo(c->hDC, rightEdge - DD(2), y + bounds->top + pen_width + 1);
678  }
679  bounds->top += border_width;
680  }
681  if (para->fmt.wBorders & 8)
682  {
683  MoveToEx(c->hDC, c->pt.x, y + para->nHeight - bounds->bottom - 1, NULL);
684  LineTo(c->hDC, rightEdge, y + para->nHeight - bounds->bottom - 1);
685  if (border_details[idx].dble) {
686  MoveToEx(c->hDC, c->pt.x + DD(1), y + para->nHeight - bounds->bottom - 1 - pen_width - 1, NULL);
687  LineTo(c->hDC, rightEdge - DD(2), y + para->nHeight - bounds->bottom - 1 - pen_width - 1);
688  }
689  bounds->bottom += border_width;
690  }
691 #undef DD
692 
693  MoveToEx(c->hDC, pt.x, pt.y, NULL);
694  SelectObject(c->hDC, oldpen);
695  DeleteObject(pen);
696  }
697 }
698 
700 {
701  ME_Paragraph *para = &paragraph->member.para;
702  if (!c->editor->bEmulateVersion10) /* v4.1 */
703  {
704  if (para->pCell)
705  {
706  RECT rc;
707  ME_Cell *cell = &para->pCell->member.cell;
708  ME_DisplayItem *paraAfterRow;
709  HPEN pen, oldPen;
710  LOGBRUSH logBrush;
711  HBRUSH brush;
712  COLORREF color;
713  POINT oldPt;
714  int width;
715  BOOL atTop = (para->pCell != para->prev_para->member.para.pCell);
716  BOOL atBottom = (para->pCell != para->next_para->member.para.pCell);
717  int top = c->pt.y + (atTop ? cell->pt.y : para->pt.y);
718  int bottom = (atBottom ?
719  c->pt.y + cell->pt.y + cell->nHeight :
720  top + para->nHeight + (atTop ? cell->yTextOffset : 0));
721  rc.left = c->pt.x + cell->pt.x;
722  rc.right = rc.left + cell->nWidth;
723  if (atTop) {
724  /* Erase gap before text if not all borders are the same height. */
725  width = max(ME_twips2pointsY(c, cell->border.top.width), 1);
726  rc.top = top + width;
727  width = cell->yTextOffset - width;
728  rc.bottom = rc.top + width;
729  if (width)
730  PatBlt(c->hDC, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY);
731  }
732  /* Draw cell borders.
733  * The order borders are draw in is left, top, bottom, right in order
734  * to be consistent with native richedit. This is noticeable from the
735  * overlap of borders of different colours. */
736  if (!(para->nFlags & MEPF_ROWEND)) {
737  rc.top = top;
738  rc.bottom = bottom;
739  if (cell->border.left.width > 0)
740  {
741  color = cell->border.left.colorRef;
742  width = max(ME_twips2pointsX(c, cell->border.left.width), 1);
743  } else {
744  color = RGB(192,192,192);
745  width = 1;
746  }
747  logBrush.lbStyle = BS_SOLID;
748  logBrush.lbColor = color;
749  logBrush.lbHatch = 0;
751  width, &logBrush, 0, NULL);
752  oldPen = SelectObject(c->hDC, pen);
753  MoveToEx(c->hDC, rc.left, rc.top, &oldPt);
754  LineTo(c->hDC, rc.left, rc.bottom);
755  SelectObject(c->hDC, oldPen);
756  DeleteObject(pen);
757  MoveToEx(c->hDC, oldPt.x, oldPt.y, NULL);
758  }
759 
760  if (atTop) {
761  if (cell->border.top.width > 0)
762  {
763  brush = CreateSolidBrush(cell->border.top.colorRef);
764  width = max(ME_twips2pointsY(c, cell->border.top.width), 1);
765  } else {
766  brush = GetStockObject(LTGRAY_BRUSH);
767  width = 1;
768  }
769  rc.top = top;
770  rc.bottom = rc.top + width;
771  FillRect(c->hDC, &rc, brush);
772  if (cell->border.top.width > 0)
773  DeleteObject(brush);
774  }
775 
776  /* Draw the bottom border if at the last paragraph in the cell, and when
777  * in the last row of the table. */
778  if (atBottom) {
779  int oldLeft = rc.left;
780  width = max(ME_twips2pointsY(c, cell->border.bottom.width), 1);
781  paraAfterRow = ME_GetTableRowEnd(paragraph)->member.para.next_para;
782  if (paraAfterRow->member.para.nFlags & MEPF_ROWSTART) {
783  ME_DisplayItem *nextEndCell;
784  nextEndCell = ME_FindItemBack(ME_GetTableRowEnd(paraAfterRow), diCell);
785  assert(nextEndCell && !nextEndCell->member.cell.next_cell);
786  rc.left = c->pt.x + nextEndCell->member.cell.pt.x;
787  /* FIXME: Native draws FROM the bottom of the table rather than
788  * TO the bottom of the table in this case, but just doing so here
789  * will cause the next row to erase the border. */
790  /*
791  rc.top = bottom;
792  rc.bottom = rc.top + width;
793  */
794  }
795  if (rc.left < rc.right) {
796  if (cell->border.bottom.width > 0) {
797  brush = CreateSolidBrush(cell->border.bottom.colorRef);
798  } else {
799  brush = GetStockObject(LTGRAY_BRUSH);
800  }
801  rc.bottom = bottom;
802  rc.top = rc.bottom - width;
803  FillRect(c->hDC, &rc, brush);
804  if (cell->border.bottom.width > 0)
805  DeleteObject(brush);
806  }
807  rc.left = oldLeft;
808  }
809 
810  /* Right border only drawn if at the end of the table row. */
811  if (!cell->next_cell->member.cell.next_cell &&
812  !(para->nFlags & MEPF_ROWSTART))
813  {
814  rc.top = top;
815  rc.bottom = bottom;
816  if (cell->border.right.width > 0) {
817  color = cell->border.right.colorRef;
818  width = max(ME_twips2pointsX(c, cell->border.right.width), 1);
819  } else {
820  color = RGB(192,192,192);
821  width = 1;
822  }
823  logBrush.lbStyle = BS_SOLID;
824  logBrush.lbColor = color;
825  logBrush.lbHatch = 0;
827  width, &logBrush, 0, NULL);
828  oldPen = SelectObject(c->hDC, pen);
829  MoveToEx(c->hDC, rc.right - 1, rc.top, &oldPt);
830  LineTo(c->hDC, rc.right - 1, rc.bottom);
831  SelectObject(c->hDC, oldPen);
832  DeleteObject(pen);
833  MoveToEx(c->hDC, oldPt.x, oldPt.y, NULL);
834  }
835  }
836  } else { /* v1.0 - 3.0 */
837  /* Draw simple table border */
838  if (para->fmt.dwMask & PFM_TABLE && para->fmt.wEffects & PFE_TABLE) {
839  HPEN pen = NULL, oldpen = NULL;
840  int i, firstX, startX, endX, rowY, rowBottom, nHeight;
841  POINT oldPt;
842  PARAFORMAT2 *pNextFmt;
843 
844  pen = CreatePen(PS_SOLID, 0, para->border.top.colorRef);
845  oldpen = SelectObject(c->hDC, pen);
846 
847  /* Find the start relative to the text */
848  firstX = c->pt.x + ME_FindItemFwd(paragraph, diRun)->member.run.pt.x;
849  /* Go back by the horizontal gap, which is stored in dxOffset */
850  firstX -= ME_twips2pointsX(c, para->fmt.dxOffset);
851  /* The left edge, stored in dxStartIndent affected just the first edge */
852  startX = firstX - ME_twips2pointsX(c, para->fmt.dxStartIndent);
853  rowY = c->pt.y + para->pt.y;
854  if (para->fmt.dwMask & PFM_SPACEBEFORE)
855  rowY += ME_twips2pointsY(c, para->fmt.dySpaceBefore);
856  nHeight = ME_FindItemFwd(paragraph, diStartRow)->member.row.nHeight;
857  rowBottom = rowY + nHeight;
858 
859  /* Draw horizontal lines */
860  MoveToEx(c->hDC, firstX, rowY, &oldPt);
861  i = para->fmt.cTabCount - 1;
862  endX = startX + ME_twips2pointsX(c, para->fmt.rgxTabs[i] & 0x00ffffff) + 1;
863  LineTo(c->hDC, endX, rowY);
864  pNextFmt = &para->next_para->member.para.fmt;
865  /* The bottom of the row only needs to be drawn if the next row is
866  * not a table. */
867  if (!(pNextFmt && pNextFmt->dwMask & PFM_TABLE && pNextFmt->wEffects &&
868  para->nRows == 1))
869  {
870  /* Decrement rowBottom to draw the bottom line within the row, and
871  * to not draw over this line when drawing the vertical lines. */
872  rowBottom--;
873  MoveToEx(c->hDC, firstX, rowBottom, NULL);
874  LineTo(c->hDC, endX, rowBottom);
875  }
876 
877  /* Draw vertical lines */
878  MoveToEx(c->hDC, firstX, rowY, NULL);
879  LineTo(c->hDC, firstX, rowBottom);
880  for (i = 0; i < para->fmt.cTabCount; i++)
881  {
882  int rightBoundary = para->fmt.rgxTabs[i] & 0x00ffffff;
883  endX = startX + ME_twips2pointsX(c, rightBoundary);
884  MoveToEx(c->hDC, endX, rowY, NULL);
885  LineTo(c->hDC, endX, rowBottom);
886  }
887 
888  MoveToEx(c->hDC, oldPt.x, oldPt.y, NULL);
889  SelectObject(c->hDC, oldpen);
890  DeleteObject(pen);
891  }
892  }
893 }
894 
896 {
897  ME_Paragraph *para = &p->member.para;
898  int x, y;
899  COLORREF old_text;
900 
901  if (para->fmt.wNumbering)
902  {
903  select_style( c, para->para_num.style );
904  old_text = SetTextColor( c->hDC, get_text_color( c, para->para_num.style, FALSE ) );
905 
906  x = c->pt.x + para->para_num.pt.x;
907  y = c->pt.y + para->pt.y + para->para_num.pt.y;
908 
909  ExtTextOutW( c->hDC, x, y, 0, NULL, para->para_num.text->szData, para->para_num.text->nLen, NULL );
910 
911  SetTextColor( c->hDC, old_text );
912  }
913 }
914 
915 static void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph)
916 {
917  int align = SetTextAlign(c->hDC, TA_BASELINE);
918  ME_DisplayItem *p;
919  ME_Run *run;
920  ME_Paragraph *para = NULL;
921  RECT rc, bounds;
922  int y;
923  int height = 0, baseline = 0, no=0;
924  BOOL visible = FALSE;
925 
926  rc.left = c->pt.x;
927  rc.right = c->rcView.right;
928 
929  assert(paragraph);
930  para = &paragraph->member.para;
931  y = c->pt.y + para->pt.y;
932  if (para->pCell)
933  {
934  ME_Cell *cell = &para->pCell->member.cell;
935  rc.left = c->pt.x + cell->pt.x;
936  rc.right = rc.left + cell->nWidth;
937  }
938  if (para->nFlags & MEPF_ROWSTART) {
939  ME_Cell *cell = &para->next_para->member.para.pCell->member.cell;
940  rc.right = c->pt.x + cell->pt.x;
941  } else if (para->nFlags & MEPF_ROWEND) {
942  ME_Cell *cell = &para->prev_para->member.para.pCell->member.cell;
943  rc.left = c->pt.x + cell->pt.x + cell->nWidth;
944  }
945  ME_DrawParaDecoration(c, para, y, &bounds);
946  y += bounds.top;
947  if (bounds.left || bounds.right) {
948  rc.left = max(rc.left, c->pt.x + bounds.left);
949  rc.right = min(rc.right, c->pt.x - bounds.right
950  + max(c->editor->sizeWindow.cx,
951  c->editor->nTotalWidth));
952  }
953 
954  for (p = paragraph->next; p != para->next_para; p = p->next)
955  {
956  switch(p->type) {
957  case diParagraph:
958  assert(FALSE);
959  break;
960  case diStartRow:
961  y += height;
962  rc.top = y;
963  if (para->nFlags & (MEPF_ROWSTART|MEPF_ROWEND)) {
964  rc.bottom = y + para->nHeight;
965  } else {
966  rc.bottom = y + p->member.row.nHeight;
967  }
968  visible = RectVisible(c->hDC, &rc);
969  if (visible)
970  PatBlt(c->hDC, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY);
971  if (bounds.right)
972  {
973  /* If scrolled to the right past the end of the text, then
974  * there may be space to the right of the paragraph border. */
975  RECT after_bdr = rc;
976  after_bdr.left = rc.right + bounds.right;
977  after_bdr.right = c->rcView.right;
978  if (RectVisible(c->hDC, &after_bdr))
979  PatBlt(c->hDC, after_bdr.left, after_bdr.top, after_bdr.right - after_bdr.left,
980  after_bdr.bottom - after_bdr.top, PATCOPY);
981  }
982  if (me_debug)
983  {
984  static const WCHAR wszRowDebug[] = {'r','o','w','[','%','d',']',0};
985  WCHAR buf[128];
986  POINT pt = c->pt;
987  wsprintfW(buf, wszRowDebug, no);
988  pt.y = 12+y;
989  ME_DebugWrite(c->hDC, &pt, buf);
990  }
991 
992  height = p->member.row.nHeight;
993  baseline = p->member.row.nBaseline;
994  break;
995  case diRun:
996  assert(para);
997  run = &p->member.run;
998  if (visible && me_debug) {
999  RECT rc;
1000  rc.left = c->pt.x + run->pt.x;
1001  rc.right = rc.left + run->nWidth;
1002  rc.top = c->pt.y + para->pt.y + run->pt.y;
1003  rc.bottom = rc.top + height;
1004  TRACE("rc = %s\n", wine_dbgstr_rect(&rc));
1006  }
1007  if (visible)
1008  ME_DrawRun(c, c->pt.x + run->pt.x,
1009  c->pt.y + para->pt.y + run->pt.y + baseline, p, para);
1010  if (me_debug)
1011  {
1012  static const WCHAR wszRunDebug[] = {'[','%','d',':','%','x',']',' ','%','l','s',0};
1013  WCHAR buf[2560];
1014  POINT pt;
1015  pt.x = c->pt.x + run->pt.x;
1016  pt.y = c->pt.y + para->pt.y + run->pt.y;
1017  wsprintfW(buf, wszRunDebug, no, p->member.run.nFlags, get_text( &p->member.run, 0 ));
1018  ME_DebugWrite(c->hDC, &pt, buf);
1019  }
1020  break;
1021  case diCell:
1022  /* Clear any space at the bottom of the cell after the text. */
1023  if (para->nFlags & (MEPF_ROWSTART|MEPF_ROWEND))
1024  break;
1025  y += height;
1026  rc.top = c->pt.y + para->pt.y + para->nHeight;
1027  rc.bottom = c->pt.y + p->member.cell.pt.y + p->member.cell.nHeight;
1028  if (RectVisible(c->hDC, &rc))
1029  PatBlt(c->hDC, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY);
1030  break;
1031  default:
1032  break;
1033  }
1034  no++;
1035  }
1036 
1037  ME_DrawTableBorders(c, paragraph);
1038  draw_para_number(c, paragraph);
1039 
1040  SetTextAlign(c->hDC, align);
1041 }
1042 
1043 void ME_ScrollAbs(ME_TextEditor *editor, int x, int y)
1044 {
1045  BOOL bScrollBarIsVisible, bScrollBarWillBeVisible;
1046  int scrollX = 0, scrollY = 0;
1047 
1048  if (editor->horz_si.nPos != x) {
1049  x = min(x, editor->horz_si.nMax);
1050  x = max(x, editor->horz_si.nMin);
1051  scrollX = editor->horz_si.nPos - x;
1052  editor->horz_si.nPos = x;
1053  if (editor->horz_si.nMax > 0xFFFF) /* scale to 16-bit value */
1054  x = MulDiv(x, 0xFFFF, editor->horz_si.nMax);
1056  }
1057 
1058  if (editor->vert_si.nPos != y) {
1059  y = min(y, editor->vert_si.nMax - (int)editor->vert_si.nPage);
1060  y = max(y, editor->vert_si.nMin);
1061  scrollY = editor->vert_si.nPos - y;
1062  editor->vert_si.nPos = y;
1063  if (editor->vert_si.nMax > 0xFFFF) /* scale to 16-bit value */
1064  y = MulDiv(y, 0xFFFF, editor->vert_si.nMax);
1066  }
1067 
1068  if (abs(scrollX) > editor->sizeWindow.cx ||
1069  abs(scrollY) > editor->sizeWindow.cy)
1071  else
1072  ITextHost_TxScrollWindowEx(editor->texthost, scrollX, scrollY,
1073  &editor->rcFormat, &editor->rcFormat,
1074  NULL, NULL, SW_INVALIDATE);
1075  ME_Repaint(editor);
1076 
1077  if (editor->hWnd)
1078  {
1079  LONG winStyle = GetWindowLongW(editor->hWnd, GWL_STYLE);
1080  if (editor->styleFlags & WS_HSCROLL)
1081  {
1082  bScrollBarIsVisible = (winStyle & WS_HSCROLL) != 0;
1083  bScrollBarWillBeVisible = (editor->nTotalWidth > editor->sizeWindow.cx
1084  && (editor->styleFlags & WS_HSCROLL))
1085  || (editor->styleFlags & ES_DISABLENOSCROLL);
1086  if (bScrollBarIsVisible != bScrollBarWillBeVisible)
1088  bScrollBarWillBeVisible);
1089  }
1090 
1091  if (editor->styleFlags & WS_VSCROLL)
1092  {
1093  bScrollBarIsVisible = (winStyle & WS_VSCROLL) != 0;
1094  bScrollBarWillBeVisible = (editor->nTotalLength > editor->sizeWindow.cy
1095  && (editor->styleFlags & WS_VSCROLL)
1096  && (editor->styleFlags & ES_MULTILINE))
1097  || (editor->styleFlags & ES_DISABLENOSCROLL);
1098  if (bScrollBarIsVisible != bScrollBarWillBeVisible)
1100  bScrollBarWillBeVisible);
1101  }
1102  }
1103  ME_UpdateScrollBar(editor);
1104 }
1105 
1106 void ME_HScrollAbs(ME_TextEditor *editor, int x)
1107 {
1108  ME_ScrollAbs(editor, x, editor->vert_si.nPos);
1109 }
1110 
1111 void ME_VScrollAbs(ME_TextEditor *editor, int y)
1112 {
1113  ME_ScrollAbs(editor, editor->horz_si.nPos, y);
1114 }
1115 
1116 void ME_ScrollUp(ME_TextEditor *editor, int cy)
1117 {
1118  ME_VScrollAbs(editor, editor->vert_si.nPos - cy);
1119 }
1120 
1121 void ME_ScrollDown(ME_TextEditor *editor, int cy)
1122 {
1123  ME_VScrollAbs(editor, editor->vert_si.nPos + cy);
1124 }
1125 
1126 void ME_ScrollLeft(ME_TextEditor *editor, int cx)
1127 {
1128  ME_HScrollAbs(editor, editor->horz_si.nPos - cx);
1129 }
1130 
1131 void ME_ScrollRight(ME_TextEditor *editor, int cx)
1132 {
1133  ME_HScrollAbs(editor, editor->horz_si.nPos + cx);
1134 }
1135 
1136 /* Calculates the visibility after a call to SetScrollRange or
1137  * SetScrollInfo with SIF_RANGE. */
1139 {
1140  if (si->fMask & SIF_DISABLENOSCROLL)
1141  return TRUE;
1142 
1143  /* This must match the check in SetScrollInfo to determine whether
1144  * to show or hide the scrollbars. */
1145  return si->nMin < si->nMax - max(si->nPage - 1, 0);
1146 }
1147 
1149 {
1150  /* Note that this is the only function that should ever call
1151  * SetScrollInfo with SIF_PAGE or SIF_RANGE. */
1152 
1153  SCROLLINFO si;
1154  BOOL bScrollBarWasVisible, bScrollBarWillBeVisible;
1155 
1156  if (ME_WrapMarkedParagraphs(editor))
1157  FIXME("ME_UpdateScrollBar had to call ME_WrapMarkedParagraphs\n");
1158 
1159  si.cbSize = sizeof(si);
1160  si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS;
1161  si.nMin = 0;
1162  if (editor->styleFlags & ES_DISABLENOSCROLL)
1163  si.fMask |= SIF_DISABLENOSCROLL;
1164 
1165  /* Update horizontal scrollbar */
1166  bScrollBarWasVisible = editor->horz_si.nMax > editor->horz_si.nPage;
1167  bScrollBarWillBeVisible = editor->nTotalWidth > editor->sizeWindow.cx;
1168  if (editor->horz_si.nPos && !bScrollBarWillBeVisible)
1169  {
1170  ME_HScrollAbs(editor, 0);
1171  /* ME_HScrollAbs will call this function,
1172  * so nothing else needs to be done here. */
1173  return;
1174  }
1175 
1176  si.nMax = editor->nTotalWidth;
1177  si.nPos = editor->horz_si.nPos;
1178  si.nPage = editor->sizeWindow.cx;
1179 
1180  if (si.nMax != editor->horz_si.nMax ||
1181  si.nPage != editor->horz_si.nPage)
1182  {
1183  TRACE("min=%d max=%d page=%d\n", si.nMin, si.nMax, si.nPage);
1184  editor->horz_si.nMax = si.nMax;
1185  editor->horz_si.nPage = si.nPage;
1186  if ((bScrollBarWillBeVisible || bScrollBarWasVisible) &&
1187  editor->styleFlags & WS_HSCROLL)
1188  {
1189  if (si.nMax > 0xFFFF)
1190  {
1191  /* Native scales the scrollbar info to 16-bit external values. */
1192  si.nPos = MulDiv(si.nPos, 0xFFFF, si.nMax);
1193  si.nMax = 0xFFFF;
1194  }
1195  if (editor->hWnd) {
1196  SetScrollInfo(editor->hWnd, SB_HORZ, &si, TRUE);
1197  } else {
1200  }
1201  /* SetScrollInfo or SetScrollRange change scrollbar visibility. */
1202  bScrollBarWasVisible = ME_PostSetScrollRangeVisibility(&si);
1203  }
1204  }
1205 
1206  if (editor->styleFlags & WS_HSCROLL)
1207  {
1208  if (si.fMask & SIF_DISABLENOSCROLL) {
1209  bScrollBarWillBeVisible = TRUE;
1210  } else if (!(editor->styleFlags & WS_HSCROLL)) {
1211  bScrollBarWillBeVisible = FALSE;
1212  }
1213 
1214  if (bScrollBarWasVisible != bScrollBarWillBeVisible)
1215  ITextHost_TxShowScrollBar(editor->texthost, SB_HORZ, bScrollBarWillBeVisible);
1216  }
1217 
1218  /* Update vertical scrollbar */
1219  bScrollBarWasVisible = editor->vert_si.nMax > editor->vert_si.nPage;
1220  bScrollBarWillBeVisible = editor->nTotalLength > editor->sizeWindow.cy &&
1221  (editor->styleFlags & ES_MULTILINE);
1222 
1223  if (editor->vert_si.nPos && !bScrollBarWillBeVisible)
1224  {
1225  ME_VScrollAbs(editor, 0);
1226  /* ME_VScrollAbs will call this function,
1227  * so nothing else needs to be done here. */
1228  return;
1229  }
1230 
1231  si.nMax = editor->nTotalLength;
1232  si.nPos = editor->vert_si.nPos;
1233  si.nPage = editor->sizeWindow.cy;
1234 
1235  if (si.nMax != editor->vert_si.nMax ||
1236  si.nPage != editor->vert_si.nPage)
1237  {
1238  TRACE("min=%d max=%d page=%d\n", si.nMin, si.nMax, si.nPage);
1239  editor->vert_si.nMax = si.nMax;
1240  editor->vert_si.nPage = si.nPage;
1241  if ((bScrollBarWillBeVisible || bScrollBarWasVisible) &&
1242  editor->styleFlags & WS_VSCROLL)
1243  {
1244  if (si.nMax > 0xFFFF)
1245  {
1246  /* Native scales the scrollbar info to 16-bit external values. */
1247  si.nPos = MulDiv(si.nPos, 0xFFFF, si.nMax);
1248  si.nMax = 0xFFFF;
1249  }
1250  if (editor->hWnd) {
1251  SetScrollInfo(editor->hWnd, SB_VERT, &si, TRUE);
1252  } else {
1255  }
1256  /* SetScrollInfo or SetScrollRange change scrollbar visibility. */
1257  bScrollBarWasVisible = ME_PostSetScrollRangeVisibility(&si);
1258  }
1259  }
1260 
1261  if (editor->styleFlags & WS_VSCROLL)
1262  {
1263  if (si.fMask & SIF_DISABLENOSCROLL) {
1264  bScrollBarWillBeVisible = TRUE;
1265  } else if (!(editor->styleFlags & WS_VSCROLL)) {
1266  bScrollBarWillBeVisible = FALSE;
1267  }
1268 
1269  if (bScrollBarWasVisible != bScrollBarWillBeVisible)
1271  bScrollBarWillBeVisible);
1272  }
1273 }
1274 
1276 {
1277  ME_Run *pRun = &pCursor->pRun->member.run;
1278  ME_DisplayItem *pRow = ME_FindItemBack(pCursor->pRun, diStartRow);
1279  ME_DisplayItem *pPara = pCursor->pPara;
1280  int x, y, yheight;
1281 
1282  assert(pRow);
1283  assert(pPara);
1284 
1285  if (editor->styleFlags & ES_AUTOHSCROLL)
1286  {
1287  x = pRun->pt.x + ME_PointFromChar(editor, pRun, pCursor->nOffset, TRUE);
1288  if (x > editor->horz_si.nPos + editor->sizeWindow.cx)
1289  x = x + 1 - editor->sizeWindow.cx;
1290  else if (x > editor->horz_si.nPos)
1291  x = editor->horz_si.nPos;
1292 
1293  if (~editor->styleFlags & ES_AUTOVSCROLL)
1294  {
1295  ME_HScrollAbs(editor, x);
1296  return;
1297  }
1298  } else {
1299  if (~editor->styleFlags & ES_AUTOVSCROLL)
1300  return;
1301  x = editor->horz_si.nPos;
1302  }
1303 
1304  y = pPara->member.para.pt.y + pRow->member.row.pt.y;
1305  yheight = pRow->member.row.nHeight;
1306 
1307  if (y < editor->vert_si.nPos)
1308  ME_ScrollAbs(editor, x, y);
1309  else if (y + yheight > editor->vert_si.nPos + editor->sizeWindow.cy)
1310  ME_ScrollAbs(editor, x, y + yheight - editor->sizeWindow.cy);
1311  else if (x != editor->horz_si.nPos)
1312  ME_ScrollAbs(editor, x, editor->vert_si.nPos);
1313 }
1314 
1315 
1316 void
1318 {
1319  ME_DisplayItem *sel_start, *sel_end;
1320  ME_DisplayItem *repaint_start = NULL, *repaint_end = NULL;
1321  int nStart, nEnd;
1322  int len = ME_GetTextLength(editor);
1323 
1324  ME_GetSelectionOfs(editor, &nStart, &nEnd);
1325  /* if both old and new selection are 0-char (= caret only), then
1326  there's no (inverted) area to be repainted, neither old nor new */
1327  if (nStart == nEnd && editor->nLastSelStart == editor->nLastSelEnd)
1328  return;
1329  ME_WrapMarkedParagraphs(editor);
1330  ME_GetSelectionParas(editor, &sel_start, &sel_end);
1331  assert(sel_start->type == diParagraph);
1332  assert(sel_end->type == diParagraph);
1333  /* last selection markers aren't always updated, which means
1334  * they can point past the end of the document */
1335  if (editor->nLastSelStart > len || editor->nLastSelEnd > len) {
1336  repaint_start = ME_FindItemFwd(editor->pBuffer->pFirst, diParagraph);
1337  repaint_end = editor->pBuffer->pLast->member.para.prev_para;
1338  } else {
1339  /* if the start part of selection is being expanded or contracted... */
1340  if (nStart < editor->nLastSelStart) {
1341  repaint_start = sel_start;
1342  repaint_end = editor->pLastSelStartPara;
1343  } else if (nStart > editor->nLastSelStart) {
1344  repaint_start = editor->pLastSelStartPara;
1345  repaint_end = sel_start;
1346  }
1347 
1348  /* if the end part of selection is being contracted or expanded... */
1349  if (nEnd < editor->nLastSelEnd) {
1350  if (!repaint_start) repaint_start = sel_end;
1351  repaint_end = editor->pLastSelEndPara;
1352  } else if (nEnd > editor->nLastSelEnd) {
1353  if (!repaint_start) repaint_start = editor->pLastSelEndPara;
1354  repaint_end = sel_end;
1355  }
1356  }
1357 
1358  if (repaint_start)
1359  ME_InvalidateParagraphRange(editor, repaint_start, repaint_end);
1360  /* remember the last invalidated position */
1361  ME_GetSelectionOfs(editor, &editor->nLastSelStart, &editor->nLastSelEnd);
1362  ME_GetSelectionParas(editor, &editor->pLastSelStartPara, &editor->pLastSelEndPara);
1364  assert(editor->pLastSelEndPara->type == diParagraph);
1365 }
1366 
1367 BOOL
1368 ME_SetZoom(ME_TextEditor *editor, int numerator, int denominator)
1369 {
1370  /* TODO: Zoom images and objects */
1371 
1372  if (numerator == 0 && denominator == 0)
1373  {
1374  editor->nZoomNumerator = editor->nZoomDenominator = 0;
1375  return TRUE;
1376  }
1377  if (numerator <= 0 || denominator <= 0)
1378  return FALSE;
1379  if (numerator * 64 <= denominator || numerator / denominator >= 64)
1380  return FALSE;
1381 
1382  editor->nZoomNumerator = numerator;
1383  editor->nZoomDenominator = denominator;
1384 
1385  ME_RewrapRepaint(editor);
1386  return TRUE;
1387 }
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:1131
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:293
#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:300
#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:1043
#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:1275
int WINAPI SelectClipRgn(_In_ HDC, _In_opt_ HRGN)
long y
Definition: polytest.cpp:48
WCHAR * szData
Definition: editstr.h:60
static void ME_DrawTableBorders(ME_Context *c, ME_DisplayItem *paragraph)
Definition: paint.c:699
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:1746
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:3595
#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:1368
#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:330
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
const WCHAR * text
Definition: package.c:1827
ULONG_PTR lbHatch
Definition: wingdi.h:1748
#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:490
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:307
static int ME_GetBorderPenWidth(const ME_Context *c, int idx)
Definition: paint.c:516
unsigned dble
Definition: paint.c:490
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:312
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
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:306
static void draw_para_number(ME_Context *c, ME_DisplayItem *p)
Definition: paint.c:895
static const struct @523 border_details[]
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:598
int nCharOfs
Definition: editstr.h:166
ME_Style * style
Definition: editstr.h:164
LONG right
Definition: windef.h:308
#define PS_GEOMETRIC
Definition: wingdi.h:582
#define lstrlenW
Definition: compat.h:415
void ME_SendRequestResize(ME_TextEditor *editor, BOOL force) DECLSPEC_HIDDEN
Definition: wrap.c:1198
#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:433
& 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:319
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
void select_style(ME_Context *c, ME_Style *s) DECLSPEC_HIDDEN
Definition: style.c:369
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:544
unsigned int idx
Definition: utils.c:41
#define TRANSPARENT
Definition: wingdi.h:949
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:581
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:334
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:1148
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:883
#define TRACE(s)
Definition: solgame.cpp:4
BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) DECLSPEC_HIDDEN
Definition: wrap.c:1093
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:1111
__wchar_t WCHAR
Definition: xmlstorage.h:180
GOFFSET * offsets
Definition: editstr.h:179
void ME_SendSelChange(ME_TextEditor *editor)
Definition: caret.c:1553
DWORD COLORREF
Definition: windef.h:300
#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:2939
COLORREF lbColor
Definition: wingdi.h:1747
const GLubyte * c
Definition: glext.h:8905
const char * wine_dbgstr_rect(const RECT *rect)
void ME_SendOldNotify(ME_TextEditor *editor, int nCode)
Definition: editor.c:5117
void ME_InvalidateSelection(ME_TextEditor *editor)
Definition: paint.c:1317
void ME_ScrollUp(ME_TextEditor *editor, int cy)
Definition: paint.c:1116
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:44
#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:41
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:1121
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 PATCOPY
Definition: wingdi.h:334
#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:1168
static void ME_DrawRun(ME_Context *c, int x, int y, ME_DisplayItem *rundi, ME_Paragraph *para)
Definition: paint.c:443
int * advances
Definition: editstr.h:178
WORD wEffects
Definition: richedit.h:669
void ME_HScrollAbs(ME_TextEditor *editor, int x)
Definition: paint.c:1106
#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:289
COLORREF colorRef
Definition: editstr.h:187
ME_Border right
Definition: editstr.h:195
unsigned width
Definition: paint.c:490
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:915
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:529
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:505
SCRIPT_ANALYSIS script_analysis
Definition: editstr.h:174
#define ITextHost_TxSetScrollPos(This, a, b, c)
Definition: editor.h:292
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:1126
#define CFM_BACKCOLOR
Definition: richedit.h:357
#define PS_DOT
Definition: wingdi.h:587
static BOOL ME_PostSetScrollRangeVisibility(SCROLLINFO *si)
Definition: paint.c:1138
#define SIF_DISABLENOSCROLL
Definition: winuser.h:1222
_Out_opt_ int * cx
Definition: commctrl.h:581
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:309
int ME_PointFromCharContext(ME_Context *c, ME_Run *pRun, int nOffset, BOOL visual_order) DECLSPEC_HIDDEN
Definition: run.c:557
void ME_DrawOLE(ME_Context *c, int x, int y, ME_Run *run, BOOL selected) DECLSPEC_HIDDEN
Definition: richole.c:5804
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:291
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:368
#define BS_SOLID
Definition: wingdi.h:1085
int yOffset
Definition: appswitch.c:59
#define ITextHost_TxViewChange(This, a)
Definition: editor.h:294
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:335
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
int ME_twips2pointsY(const ME_Context *c, int y)
Definition: paint.c:161
int ME_GetTextLength(ME_TextEditor *editor)
Definition: caret.c:83
union tagME_DisplayItem::@521 member
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