ReactOS 0.4.15-dev-5667-ged97270
wrap.c File Reference
#include "editor.h"
Include dependency graph for wrap.c:

Go to the source code of this file.

Classes

struct  tagME_WrapContext
 

Typedefs

typedef struct tagME_WrapContext ME_WrapContext
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (richedit)
 
static BOOL get_run_glyph_buffers (ME_Run *run)
 
static HRESULT shape_run (ME_Context *c, ME_Run *run)
 
static void calc_run_extent (ME_Context *c, const ME_Paragraph *para, int startx, ME_Run *run)
 
static ME_DisplayItemsplit_run_extents (ME_WrapContext *wc, ME_DisplayItem *item, int nVChar)
 
static int find_split_point (ME_Context *c, int cx, ME_Run *run)
 
static ME_DisplayItemME_MakeRow (int height, int baseline, int width)
 
static void ME_BeginRow (ME_WrapContext *wc)
 
static void layout_row (ME_DisplayItem *start, const ME_DisplayItem *end)
 
static void ME_InsertRowStart (ME_WrapContext *wc, const ME_DisplayItem *pEnd)
 
static void ME_WrapEndParagraph (ME_WrapContext *wc, ME_DisplayItem *p)
 
static void ME_WrapSizeRun (ME_WrapContext *wc, ME_DisplayItem *p)
 
static int find_non_whitespace (const WCHAR *s, int len, int start)
 
static int reverse_find_non_whitespace (const WCHAR *s, int start)
 
static int reverse_find_whitespace (const WCHAR *s, int start)
 
static ME_DisplayItemME_MaximizeSplit (ME_WrapContext *wc, ME_DisplayItem *p, int i)
 
static ME_DisplayItemME_SplitByBacktracking (ME_WrapContext *wc, ME_DisplayItem *p, int loc)
 
static ME_DisplayItemME_WrapHandleRun (ME_WrapContext *wc, ME_DisplayItem *p)
 
static int ME_GetParaLineSpace (ME_Context *c, ME_Paragraph *para)
 
static void ME_PrepareParagraphForWrapping (ME_TextEditor *editor, ME_Context *c, ME_DisplayItem *tp)
 
static HRESULT itemize_para (ME_Context *c, ME_DisplayItem *p)
 
static HRESULT shape_para (ME_Context *c, ME_DisplayItem *p)
 
static void ME_WrapTextParagraph (ME_TextEditor *editor, ME_Context *c, ME_DisplayItem *tp)
 
static void ME_MarkRepaintEnd (ME_DisplayItem *para, ME_DisplayItem **repaint_start, ME_DisplayItem **repaint_end)
 
static void adjust_para_y (ME_DisplayItem *item, ME_Context *c, ME_DisplayItem *repaint_start, ME_DisplayItem *repaint_end)
 
BOOL ME_WrapMarkedParagraphs (ME_TextEditor *editor)
 
void ME_InvalidateParagraphRange (ME_TextEditor *editor, ME_DisplayItem *start_para, ME_DisplayItem *last_para)
 
void ME_SendRequestResize (ME_TextEditor *editor, BOOL force)
 

Typedef Documentation

◆ ME_WrapContext

Function Documentation

◆ adjust_para_y()

static void adjust_para_y ( ME_DisplayItem item,
ME_Context c,
ME_DisplayItem repaint_start,
ME_DisplayItem repaint_end 
)
static

Definition at line 979 of file wrap.c.

980{
981 if (item->member.para.nFlags & MEPF_ROWSTART)
982 {
984 ME_DisplayItem *endRowPara;
985 int borderWidth = 0;
986 cell->member.cell.pt = c->pt;
987 /* Offset the text by the largest top border width. */
988 while (cell->member.cell.next_cell)
989 {
990 borderWidth = max(borderWidth, cell->member.cell.border.top.width);
991 cell = cell->member.cell.next_cell;
992 }
993 endRowPara = ME_FindItemFwd(cell, diParagraph);
994 assert(endRowPara->member.para.nFlags & MEPF_ROWEND);
995 if (borderWidth > 0)
996 {
997 borderWidth = max(ME_twips2pointsY(c, borderWidth), 1);
998 while (cell)
999 {
1000 cell->member.cell.yTextOffset = borderWidth;
1001 cell = cell->member.cell.prev_cell;
1002 }
1003 c->pt.y += borderWidth;
1004 }
1005 if (endRowPara->member.para.fmt.dxStartIndent > 0)
1006 {
1007 int dxStartIndent = endRowPara->member.para.fmt.dxStartIndent;
1008 cell = ME_FindItemFwd(item, diCell);
1009 cell->member.cell.pt.x += ME_twips2pointsX(c, dxStartIndent);
1010 c->pt.x = cell->member.cell.pt.x;
1011 }
1012 }
1013 else if (item->member.para.nFlags & MEPF_ROWEND)
1014 {
1015 /* Set all the cells to the height of the largest cell */
1016 ME_DisplayItem *startRowPara;
1017 int prevHeight, nHeight, bottomBorder = 0;
1019 item->member.para.nWidth = cell->member.cell.pt.x + cell->member.cell.nWidth;
1020 if (!(item->member.para.next_para->member.para.nFlags & MEPF_ROWSTART))
1021 {
1022 /* Last row, the bottom border is added to the height. */
1023 cell = cell->member.cell.prev_cell;
1024 while (cell)
1025 {
1026 bottomBorder = max(bottomBorder, cell->member.cell.border.bottom.width);
1027 cell = cell->member.cell.prev_cell;
1028 }
1029 bottomBorder = ME_twips2pointsY(c, bottomBorder);
1030 cell = ME_FindItemBack(item, diCell);
1031 }
1032 prevHeight = cell->member.cell.nHeight;
1033 nHeight = cell->member.cell.prev_cell->member.cell.nHeight + bottomBorder;
1034 cell->member.cell.nHeight = nHeight;
1035 item->member.para.nHeight = nHeight;
1036 cell = cell->member.cell.prev_cell;
1037 cell->member.cell.nHeight = nHeight;
1038 while (cell->member.cell.prev_cell)
1039 {
1040 cell = cell->member.cell.prev_cell;
1041 cell->member.cell.nHeight = nHeight;
1042 }
1043 /* Also set the height of the start row paragraph */
1044 startRowPara = ME_FindItemBack(cell, diParagraph);
1045 startRowPara->member.para.nHeight = nHeight;
1046 c->pt.x = startRowPara->member.para.pt.x;
1047 c->pt.y = cell->member.cell.pt.y + nHeight;
1048 if (prevHeight < nHeight)
1049 {
1050 /* The height of the cells has grown, so invalidate the bottom of
1051 * the cells. */
1052 ME_MarkRepaintEnd(item, &repaint_start, &repaint_end);
1053 cell = ME_FindItemBack(item, diCell);
1054 while (cell)
1055 {
1056 ME_MarkRepaintEnd(ME_FindItemBack(cell, diParagraph), &repaint_start, &repaint_end);
1057 cell = cell->member.cell.prev_cell;
1058 }
1059 }
1060 }
1061 else if (item->member.para.pCell &&
1062 item->member.para.pCell != item->member.para.next_para->member.para.pCell)
1063 {
1064 /* The next paragraph is in the next cell in the table row. */
1065 ME_Cell *cell = &item->member.para.pCell->member.cell;
1066 cell->nHeight = c->pt.y + item->member.para.nHeight - cell->pt.y;
1067
1068 /* Propagate the largest height to the end so that it can be easily
1069 * sent back to all the cells at the end of the row. */
1070 if (cell->prev_cell)
1071 cell->nHeight = max(cell->nHeight, cell->prev_cell->member.cell.nHeight);
1072
1073 c->pt.x = cell->pt.x + cell->nWidth;
1074 c->pt.y = cell->pt.y;
1075 cell->next_cell->member.cell.pt = c->pt;
1076 if (!(item->member.para.next_para->member.para.nFlags & MEPF_ROWEND))
1077 c->pt.y += cell->yTextOffset;
1078 }
1079 else
1080 {
1081 if (item->member.para.pCell)
1082 {
1083 /* Next paragraph in the same cell. */
1084 c->pt.x = item->member.para.pCell->member.cell.pt.x;
1085 }
1086 else
1087 /* Normal paragraph */
1088 c->pt.x = 0;
1089 c->pt.y += item->member.para.nHeight;
1090 }
1091}
#define assert(x)
Definition: debug.h:53
int ME_twips2pointsY(const ME_Context *c, int y) DECLSPEC_HIDDEN
Definition: paint.c:161
int ME_twips2pointsX(const ME_Context *c, int x) DECLSPEC_HIDDEN
Definition: paint.c:153
ME_DisplayItem * ME_FindItemBack(ME_DisplayItem *di, ME_DIType nTypeOrClass) DECLSPEC_HIDDEN
Definition: list.c:111
ME_DisplayItem * ME_FindItemFwd(ME_DisplayItem *di, ME_DIType nTypeOrClass) DECLSPEC_HIDDEN
Definition: list.c:134
#define MEPF_ROWSTART
Definition: editstr.h:144
#define MEPF_ROWEND
Definition: editstr.h:145
@ diCell
Definition: editstr.h:86
@ diParagraph
Definition: editstr.h:85
const GLubyte * c
Definition: glext.h:8905
static ATOM item
Definition: dde.c:856
LONG dxStartIndent
Definition: richedit.h:670
ME_Border bottom
Definition: editstr.h:190
ME_Border top
Definition: editstr.h:188
struct tagME_DisplayItem * prev_cell
Definition: editstr.h:229
POINT pt
Definition: editstr.h:226
int nHeight
Definition: editstr.h:227
struct tagME_DisplayItem * next_cell
Definition: editstr.h:229
ME_BorderRect border
Definition: editstr.h:225
int yTextOffset
Definition: editstr.h:228
int nWidth
Definition: editstr.h:227
ME_Cell cell
Definition: editstr.h:261
union tagME_DisplayItem::@523 member
ME_Paragraph para
Definition: editstr.h:262
PARAFORMAT2 fmt
Definition: editstr.h:204
long y
Definition: polytest.cpp:48
long x
Definition: polytest.cpp:48
#define max(a, b)
Definition: svc.c:63
static void ME_MarkRepaintEnd(ME_DisplayItem *para, ME_DisplayItem **repaint_start, ME_DisplayItem **repaint_end)
Definition: wrap.c:970

Referenced by ME_WrapMarkedParagraphs().

◆ calc_run_extent()

static void calc_run_extent ( ME_Context c,
const ME_Paragraph para,
int  startx,
ME_Run run 
)
static

Definition at line 115 of file wrap.c.

116{
117 if (run->nFlags & MERF_HIDDEN) run->nWidth = 0;
118 else
119 {
120 SIZE size = ME_GetRunSizeCommon( c, para, run, run->len, startx, &run->nAscent, &run->nDescent );
121 run->nWidth = size.cx;
122 }
123}
SIZE ME_GetRunSizeCommon(ME_Context *c, const ME_Paragraph *para, ME_Run *run, int nLen, int startx, int *pAscent, int *pDescent) DECLSPEC_HIDDEN
Definition: run.c:616
#define MERF_HIDDEN
Definition: editstr.h:126
GLsizeiptr size
Definition: glext.h:5919
int nAscent
Definition: editstr.h:166
int nDescent
Definition: editstr.h:166
int nWidth
Definition: editstr.h:164
int nFlags
Definition: editstr.h:165
int len
Definition: editstr.h:163

Referenced by ME_WrapHandleRun(), ME_WrapSizeRun(), and split_run_extents().

◆ find_non_whitespace()

static int find_non_whitespace ( const WCHAR s,
int  len,
int  start 
)
static

Definition at line 424 of file wrap.c.

425{
426 int i;
427 for (i = start; i < len && ME_IsWSpace( s[i] ); i++)
428 ;
429
430 return i;
431}
static int ME_IsWSpace(WCHAR ch)
Definition: editor.h:101
GLuint start
Definition: gl.h:1545
GLdouble s
Definition: gl.h:2039
GLenum GLsizei len
Definition: glext.h:6722
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

Referenced by ME_WrapHandleRun().

◆ find_split_point()

static int find_split_point ( ME_Context c,
int  cx,
ME_Run run 
)
static

Definition at line 174 of file wrap.c.

175{
176 if (!run->len || cx <= 0) return 0;
177 return ME_CharFromPointContext( c, cx, run, FALSE, FALSE );
178}
#define FALSE
Definition: types.h:117
int ME_CharFromPointContext(ME_Context *c, int cx, ME_Run *run, BOOL closest, BOOL visual_order) DECLSPEC_HIDDEN
Definition: run.c:462
_Out_opt_ int * cx
Definition: commctrl.h:585

Referenced by ME_SplitByBacktracking().

◆ get_run_glyph_buffers()

static BOOL get_run_glyph_buffers ( ME_Run run)
static

Definition at line 52 of file wrap.c.

53{
54 heap_free( run->glyphs );
55 run->glyphs = heap_alloc( run->max_glyphs * (sizeof(WORD) + sizeof(SCRIPT_VISATTR) + sizeof(int) + sizeof(GOFFSET)) );
56 if (!run->glyphs) return FALSE;
57
58 run->vis_attrs = (SCRIPT_VISATTR*)((char*)run->glyphs + run->max_glyphs * sizeof(WORD));
59 run->advances = (int*)((char*)run->glyphs + run->max_glyphs * (sizeof(WORD) + sizeof(SCRIPT_VISATTR)));
60 run->offsets = (GOFFSET*)((char*)run->glyphs + run->max_glyphs * (sizeof(WORD) + sizeof(SCRIPT_VISATTR) + sizeof(int)));
61
62 return TRUE;
63}
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
static BOOL heap_free(void *mem)
Definition: appwiz.h:75
#define TRUE
Definition: types.h:120
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
unsigned short WORD
Definition: ntddk_ex.h:93
GOFFSET * offsets
Definition: editstr.h:175
SCRIPT_VISATTR * vis_attrs
Definition: editstr.h:173
int * advances
Definition: editstr.h:174
WORD * glyphs
Definition: editstr.h:172
int max_glyphs
Definition: editstr.h:171

Referenced by shape_run().

◆ itemize_para()

static HRESULT itemize_para ( ME_Context c,
ME_DisplayItem p 
)
static

Definition at line 758 of file wrap.c.

759{
760 ME_Paragraph *para = &p->member.para;
761 ME_Run *run;
762 ME_DisplayItem *di;
763 SCRIPT_ITEM buf[16], *items = buf;
764 int items_passed = ARRAY_SIZE( buf ), num_items, cur_item;
766 FALSE, FALSE, 0 };
768 HRESULT hr;
769
770 assert( p->type == diParagraph );
771
772 if (para->fmt.dwMask & PFM_RTLPARA && para->fmt.wEffects & PFE_RTLPARA)
773 state.uBidiLevel = 1;
774
775 TRACE( "Base embedding level %d\n", state.uBidiLevel );
776
777 while (1)
778 {
779 hr = ScriptItemize( para->text->szData, para->text->nLen, items_passed, &control,
780 &state, items, &num_items );
781 if (hr != E_OUTOFMEMORY) break; /* may not be enough items if hr == E_OUTOFMEMORY */
782 if (items_passed > para->text->nLen + 1) break; /* something else has gone wrong */
783 items_passed *= 2;
784 if (items == buf)
785 items = heap_alloc( items_passed * sizeof( *items ) );
786 else
787 items = heap_realloc( items, items_passed * sizeof( *items ) );
788 if (!items) break;
789 }
790 if (FAILED( hr )) goto end;
791
792 if (TRACE_ON( richedit ))
793 {
794 TRACE( "got items:\n" );
795 for (cur_item = 0; cur_item < num_items; cur_item++)
796 {
797 TRACE( "\t%d - %d RTL %d bidi level %d\n", items[cur_item].iCharPos, items[cur_item+1].iCharPos - 1,
798 items[cur_item].a.fRTL, items[cur_item].a.s.uBidiLevel );
799 }
800
801 TRACE( "before splitting runs into ranges\n" );
802 for (di = p->next; di != p->member.para.next_para; di = di->next)
803 {
804 if (di->type != diRun) continue;
805 TRACE( "\t%d: %s\n", di->member.run.nCharOfs, debugstr_run( &di->member.run ) );
806 }
807 }
808
809 /* split runs into ranges at item boundaries */
810 for (di = p->next, cur_item = 0; di != p->member.para.next_para; di = di->next)
811 {
812 if (di->type != diRun) continue;
813 run = &di->member.run;
814
815 if (run->nCharOfs == items[cur_item+1].iCharPos) cur_item++;
816
817 items[cur_item].a.fLogicalOrder = TRUE;
818 run->script_analysis = items[cur_item].a;
819
820 if (run->nFlags & MERF_ENDPARA) break; /* don't split eop runs */
821
822 if (run->nCharOfs + run->len > items[cur_item+1].iCharPos)
823 {
824 ME_Cursor cursor = {p, di, items[cur_item+1].iCharPos - run->nCharOfs};
825 ME_SplitRunSimple( c->editor, &cursor );
826 }
827 }
828
829 if (TRACE_ON( richedit ))
830 {
831 TRACE( "after splitting into ranges\n" );
832 for (di = p->next; di != p->member.para.next_para; di = di->next)
833 {
834 if (di->type != diRun) continue;
835 TRACE( "\t%d: %s\n", di->member.run.nCharOfs, debugstr_run( &di->member.run ) );
836 }
837 }
838
839 para->nFlags |= MEPF_COMPLEX;
840
841end:
842 if (items != buf) heap_free( items );
843 return hr;
844}
static int state
Definition: maze.c:121
static void * heap_realloc(void *mem, size_t len)
Definition: appwiz.h:70
#define ARRAY_SIZE(a)
Definition: main.h:24
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define TRACE_ON(x)
Definition: compat.h:75
HRESULT WINAPI ScriptItemize(const WCHAR *pwcInChars, int cInChars, int cMaxItems, const SCRIPT_CONTROL *psControl, const SCRIPT_STATE *psState, SCRIPT_ITEM *pItems, int *pcItems)
Definition: usp10.c:1853
ME_DisplayItem * ME_SplitRunSimple(ME_TextEditor *editor, ME_Cursor *cursor) DECLSPEC_HIDDEN
Definition: run.c:258
static const char * debugstr_run(const ME_Run *run)
Definition: editor.h:46
#define MERF_ENDPARA
Definition: editstr.h:122
#define MEPF_COMPLEX
Definition: editstr.h:146
@ diRun
Definition: editstr.h:87
GLuint GLuint end
Definition: gl.h:1545
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLfloat GLfloat p
Definition: glext.h:8902
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
const char cursor[]
Definition: icontest.c:13
#define FAILED(hr)
Definition: intsafe.h:51
static TCHAR * items[]
Definition: page1.c:45
#define PFE_RTLPARA
Definition: richedit.h:932
#define PFM_RTLPARA
Definition: richedit.h:856
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
DWORD dwMask
Definition: richedit.h:667
WORD wEffects
Definition: richedit.h:669
ME_DIType type
Definition: editstr.h:256
struct tagME_DisplayItem * next
Definition: editstr.h:257
ME_String * text
Definition: editstr.h:205
int nCharOfs
Definition: editstr.h:162
SCRIPT_ANALYSIS script_analysis
Definition: editstr.h:170
WCHAR * szData
Definition: editstr.h:56
int nLen
Definition: editstr.h:57
#define LANG_USER_DEFAULT
Definition: tnerror.cpp:50

Referenced by ME_WrapTextParagraph().

◆ layout_row()

static void layout_row ( ME_DisplayItem start,
const ME_DisplayItem end 
)
static

Definition at line 236 of file wrap.c.

237{
239 int i, num_runs = 0;
240 int buf[16 * 5]; /* 5 arrays - 4 of int & 1 of BYTE, alloc space for 5 of ints */
241 int *vis_to_log = buf, *log_to_vis, *widths, *pos;
242 BYTE *levels;
243 BOOL found_black = FALSE;
244
245 for (p = end->prev; p != start->prev; p = p->prev)
246 {
247 if (p->type == diRun)
248 {
249 if (!found_black) found_black = !(p->member.run.nFlags & (MERF_WHITESPACE | MERF_ENDPARA));
250 if (found_black) num_runs++;
251 }
252 }
253
254 TRACE("%d runs\n", num_runs);
255 if (!num_runs) return;
256
257 if (num_runs > ARRAY_SIZE( buf ) / 5)
258 vis_to_log = heap_alloc( num_runs * sizeof(int) * 5 );
259
260 log_to_vis = vis_to_log + num_runs;
261 widths = vis_to_log + 2 * num_runs;
262 pos = vis_to_log + 3 * num_runs;
263 levels = (BYTE*)(vis_to_log + 4 * num_runs);
264
265 for (i = 0, p = start; i < num_runs; p = p->next)
266 {
267 if (p->type == diRun)
268 {
269 levels[i] = p->member.run.script_analysis.s.uBidiLevel;
270 widths[i] = p->member.run.nWidth;
271 TRACE( "%d: level %d width %d\n", i, levels[i], widths[i] );
272 i++;
273 }
274 }
275
276 ScriptLayout( num_runs, levels, vis_to_log, log_to_vis );
277
278 pos[0] = start->member.run.para->pt.x;
279 for (i = 1; i < num_runs; i++)
280 pos[i] = pos[i - 1] + widths[ vis_to_log[ i - 1 ] ];
281
282 for (i = 0, p = start; i < num_runs; p = p->next)
283 {
284 if (p->type == diRun)
285 {
286 p->member.run.pt.x = pos[ log_to_vis[ i ] ];
287 TRACE( "%d: x = %d\n", i, p->member.run.pt.x );
288 i++;
289 }
290 }
291
292 if (vis_to_log != buf) heap_free( vis_to_log );
293}
HRESULT WINAPI ScriptLayout(int runs, const BYTE *level, int *vistolog, int *logtovis)
Definition: usp10.c:3752
#define MERF_WHITESPACE
Definition: editstr.h:120
unsigned int BOOL
Definition: ntddk_ex.h:94
GLsizei levels
Definition: glext.h:7884
unsigned char BYTE
Definition: xxhash.c:193

Referenced by ME_InsertRowStart().

◆ ME_BeginRow()

static void ME_BeginRow ( ME_WrapContext wc)
static

Definition at line 190 of file wrap.c.

191{
192 PARAFORMAT2 *pFmt;
193 ME_DisplayItem *para = wc->pPara;
194
195 pFmt = &para->member.para.fmt;
196 wc->pRowStart = NULL;
197 wc->bOverflown = FALSE;
199 wc->bWordWrap = wc->context->editor->bWordWrap;
201 wc->nAvailWidth = 0;
202 wc->bWordWrap = FALSE;
203 if (para->member.para.nFlags & MEPF_ROWEND)
204 {
205 ME_Cell *cell = &ME_FindItemBack(para, diCell)->member.cell;
206 cell->nWidth = 0;
207 }
208 } else if (para->member.para.pCell) {
209 ME_Cell *cell = &para->member.para.pCell->member.cell;
210 int width;
211
212 width = cell->nRightBoundary;
213 if (cell->prev_cell)
214 width -= cell->prev_cell->member.cell.nRightBoundary;
215 if (!cell->prev_cell)
216 {
217 int rowIndent = ME_GetTableRowEnd(para)->member.para.fmt.dxStartIndent;
218 width -= rowIndent;
219 }
220 cell->nWidth = max(ME_twips2pointsX(wc->context, width), 0);
221
222 wc->nAvailWidth = cell->nWidth
223 - (wc->nRow ? wc->nLeftMargin : wc->nFirstMargin) - wc->nRightMargin;
224 wc->bWordWrap = TRUE;
225 } else {
227 - (wc->nRow ? wc->nLeftMargin : wc->nFirstMargin) - wc->nRightMargin;
228 }
229 wc->pt.x = wc->context->pt.x;
230 if (wc->context->editor->bEmulateVersion10 && /* v1.0 - 3.0 */
231 pFmt->dwMask & PFM_TABLE && pFmt->wEffects & PFE_TABLE)
232 /* Shift the text down because of the border. */
233 wc->pt.y++;
234}
#define NULL
Definition: types.h:112
ME_DisplayItem * ME_GetTableRowEnd(ME_DisplayItem *para) DECLSPEC_HIDDEN
Definition: table.c:136
GLint GLint GLsizei width
Definition: gl.h:1546
#define PFM_TABLE
Definition: richedit.h:870
#define PFE_TABLE
Definition: richedit.h:944
int nRightBoundary
Definition: editstr.h:224
int nAvailWidth
Definition: editstr.h:455
POINT pt
Definition: editstr.h:452
ME_TextEditor * editor
Definition: editstr.h:460
struct tagME_DisplayItem * pCell
Definition: editstr.h:207
BOOL bEmulateVersion10
Definition: editstr.h:385
ME_DisplayItem * pLastSplittableRun
Definition: wrap.c:49
int nLeftMargin
Definition: wrap.c:39
int nAvailWidth
Definition: wrap.c:42
int nRightMargin
Definition: wrap.c:39
ME_DisplayItem * pRowStart
Definition: wrap.c:47
ME_DisplayItem * pPara
Definition: wrap.c:46
int nFirstMargin
Definition: wrap.c:40
POINT pt
Definition: wrap.c:44
BOOL bOverflown
Definition: wrap.c:45
ME_Context * context
Definition: wrap.c:38
BOOL bWordWrap
Definition: wrap.c:45

Referenced by ME_InsertRowStart(), and ME_WrapTextParagraph().

◆ ME_GetParaLineSpace()

static int ME_GetParaLineSpace ( ME_Context c,
ME_Paragraph para 
)
static

Definition at line 707 of file wrap.c.

708{
709 int sp = 0, ls = 0;
710 if (!(para->fmt.dwMask & PFM_LINESPACING)) return 0;
711
712 /* FIXME: how to compute simply the line space in ls ??? */
713 /* FIXME: does line spacing include the line itself ??? */
714 switch (para->fmt.bLineSpacingRule)
715 {
716 case 0: sp = ls; break;
717 case 1: sp = (3 * ls) / 2; break;
718 case 2: sp = 2 * ls; break;
719 case 3: sp = ME_twips2pointsY(c, para->fmt.dyLineSpacing); if (sp < ls) sp = ls; break;
720 case 4: sp = ME_twips2pointsY(c, para->fmt.dyLineSpacing); break;
721 case 5: sp = para->fmt.dyLineSpacing / 20; break;
722 default: FIXME("Unsupported spacing rule value %d\n", para->fmt.bLineSpacingRule);
723 }
724 if (c->editor->nZoomNumerator == 0)
725 return sp;
726 else
727 return sp * c->editor->nZoomNumerator / c->editor->nZoomDenominator;
728}
void ls(int argc, const char *argv[])
Definition: cmds.c:1136
#define FIXME(fmt,...)
Definition: debug.h:111
static const WCHAR sp[]
Definition: suminfo.c:287
#define PFM_LINESPACING
Definition: richedit.h:849
BYTE bLineSpacingRule
Definition: richedit.h:678
LONG dyLineSpacing
Definition: richedit.h:676

Referenced by ME_WrapTextParagraph().

◆ ME_InsertRowStart()

static void ME_InsertRowStart ( ME_WrapContext wc,
const ME_DisplayItem pEnd 
)
static

Definition at line 295 of file wrap.c.

296{
298 ME_Paragraph *para = &wc->pPara->member.para;
299 BOOL bSkippingSpaces = TRUE;
300 int ascent = 0, descent = 0, width=0, shift = 0, align = 0;
301
302 /* Include height of para numbering label */
303 if (wc->nRow == 0 && para->fmt.wNumbering)
304 {
305 ascent = para->para_num.style->tm.tmAscent;
306 descent = para->para_num.style->tm.tmDescent;
307 }
308
309 for (p = pEnd->prev; p!=wc->pRowStart->prev; p = p->prev)
310 {
311 /* ENDPARA run shouldn't affect row height, except if it's the only run in the paragraph */
312 if (p->type==diRun && ((p==wc->pRowStart) || !(p->member.run.nFlags & MERF_ENDPARA))) { /* FIXME add more run types */
313 if (p->member.run.nAscent>ascent)
314 ascent = p->member.run.nAscent;
315 if (p->member.run.nDescent>descent)
316 descent = p->member.run.nDescent;
317 if (bSkippingSpaces)
318 {
319 /* Exclude space characters from run width.
320 * Other whitespace or delimiters are not treated this way. */
321 int len = p->member.run.len;
322 WCHAR *text = get_text( &p->member.run, len - 1 );
323
324 assert (len);
325 if (~p->member.run.nFlags & MERF_GRAPHICS)
326 while (len && *(text--) == ' ')
327 len--;
328 if (len)
329 {
330 if (len == p->member.run.len)
331 width += p->member.run.nWidth;
332 else
333 width += ME_PointFromCharContext( wc->context, &p->member.run, len, FALSE );
334 }
335 bSkippingSpaces = !len;
336 } else if (!(p->member.run.nFlags & MERF_ENDPARA))
337 width += p->member.run.nWidth;
338 }
339 }
340
341 para->nWidth = max(para->nWidth, width);
342 row = ME_MakeRow(ascent+descent, ascent, width);
343 if (wc->context->editor->bEmulateVersion10 && /* v1.0 - 3.0 */
344 (para->fmt.dwMask & PFM_TABLE) && (para->fmt.wEffects & PFE_TABLE))
345 {
346 /* The text was shifted down in ME_BeginRow so move the wrap context
347 * back to where it should be. */
348 wc->pt.y--;
349 /* The height of the row is increased by the borders. */
350 row->member.row.nHeight += 2;
351 }
352 row->member.row.pt = wc->pt;
353 row->member.row.nLMargin = (!wc->nRow ? wc->nFirstMargin : wc->nLeftMargin);
354 row->member.row.nRMargin = wc->nRightMargin;
356 align = para->fmt.wAlignment;
357 if (align == PFA_CENTER)
358 shift = max((wc->nAvailWidth-width)/2, 0);
359 if (align == PFA_RIGHT)
360 shift = max(wc->nAvailWidth-width, 0);
361
362 if (para->nFlags & MEPF_COMPLEX) layout_row( wc->pRowStart, pEnd );
363
364 row->member.row.pt.x = row->member.row.nLMargin + shift;
365 for (p = wc->pRowStart; p!=pEnd; p = p->next)
366 {
367 if (p->type==diRun) { /* FIXME add more run types */
368 p->member.run.pt.x += row->member.row.nLMargin+shift;
369 }
370 }
371
372 if (wc->nRow == 0 && para->fmt.wNumbering)
373 {
374 para->para_num.pt.x = wc->nParaNumOffset + shift;
375 para->para_num.pt.y = wc->pt.y + row->member.row.nBaseline;
376 }
377
379 wc->nRow++;
380 wc->pt.y += row->member.row.nHeight;
381 ME_BeginRow(wc);
382}
const WCHAR * text
Definition: package.c:1799
struct png_info_def *typedef unsigned char **typedef struct png_info_def *typedef struct png_info_def *typedef struct png_info_def *typedef unsigned char ** row
Definition: typeof.h:78
int align(int length, int align)
Definition: dsound8.c:36
int ME_PointFromCharContext(ME_Context *c, ME_Run *pRun, int nOffset, BOOL visual_order) DECLSPEC_HIDDEN
Definition: run.c:557
void ME_InsertBefore(ME_DisplayItem *diWhere, ME_DisplayItem *diWhat) DECLSPEC_HIDDEN
Definition: list.c:26
static WCHAR * get_text(const ME_Run *run, int offset)
Definition: editor.h:41
#define MERF_GRAPHICS
Definition: editstr.h:105
#define shift
Definition: input.c:1755
#define PFA_RIGHT
Definition: richedit.h:922
#define PFA_CENTER
Definition: richedit.h:923
#define PFM_ALIGNMENT
Definition: richedit.h:841
WORD wAlignment
Definition: richedit.h:673
WORD wNumbering
Definition: richedit.h:668
struct tagME_DisplayItem * prev
Definition: editstr.h:257
struct para_num para_num
Definition: editstr.h:215
int nParaNumOffset
Definition: wrap.c:41
static ME_DisplayItem * ME_MakeRow(int height, int baseline, int width)
Definition: wrap.c:180
static void layout_row(ME_DisplayItem *start, const ME_DisplayItem *end)
Definition: wrap.c:236
static void ME_BeginRow(ME_WrapContext *wc)
Definition: wrap.c:190
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by ME_WrapEndParagraph(), and ME_WrapHandleRun().

◆ ME_InvalidateParagraphRange()

void ME_InvalidateParagraphRange ( ME_TextEditor editor,
ME_DisplayItem start_para,
ME_DisplayItem last_para 
)

Definition at line 1168 of file wrap.c.

1171{
1172 ME_Context c;
1173 RECT rc;
1174 int ofs;
1175
1176 ME_InitContext(&c, editor, ITextHost_TxGetDC(editor->texthost));
1177 rc = c.rcView;
1178 ofs = editor->vert_si.nPos;
1179
1180 if (start_para) {
1181 start_para = ME_GetOuterParagraph(start_para);
1182 last_para = ME_GetOuterParagraph(last_para);
1183 rc.top = c.rcView.top + start_para->member.para.pt.y - ofs;
1184 } else {
1185 rc.top = c.rcView.top + editor->nTotalLength - ofs;
1186 }
1187 if (editor->nTotalLength < editor->nLastTotalLength)
1188 rc.bottom = c.rcView.top + editor->nLastTotalLength - ofs;
1189 else
1190 rc.bottom = c.rcView.top + last_para->member.para.pt.y + last_para->member.para.nHeight - ofs;
1192
1194}
void ME_DestroyContext(ME_Context *c)
Definition: context.c:44
void ME_InitContext(ME_Context *c, ME_TextEditor *editor, HDC hDC)
Definition: context.c:23
#define ITextHost_TxInvalidateRect(This, a, b)
Definition: editor.h:293
ME_DisplayItem * ME_GetOuterParagraph(ME_DisplayItem *para) DECLSPEC_HIDDEN
Definition: table.c:172
#define ITextHost_TxGetDC(This)
Definition: editor.h:287
#define c
Definition: ke_i.h:80
SCROLLINFO vert_si
Definition: editstr.h:439
ITextHost * texthost
Definition: editstr.h:383
int nLastTotalLength
Definition: editstr.h:392
LONG bottom
Definition: windef.h:309
LONG top
Definition: windef.h:307

Referenced by ME_InvalidateSelection(), and ME_WrapMarkedParagraphs().

◆ ME_MakeRow()

static ME_DisplayItem * ME_MakeRow ( int  height,
int  baseline,
int  width 
)
static

Definition at line 180 of file wrap.c.

181{
183
184 item->member.row.nHeight = height;
185 item->member.row.nBaseline = baseline;
186 item->member.row.nWidth = width;
187 return item;
188}
ME_DisplayItem * ME_MakeDI(ME_DIType type) DECLSPEC_HIDDEN
Definition: list.c:178
@ diStartRow
Definition: editstr.h:88
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546

Referenced by ME_InsertRowStart().

◆ ME_MarkRepaintEnd()

static void ME_MarkRepaintEnd ( ME_DisplayItem para,
ME_DisplayItem **  repaint_start,
ME_DisplayItem **  repaint_end 
)
static

Definition at line 970 of file wrap.c.

973{
974 if (!*repaint_start)
975 *repaint_start = para;
976 *repaint_end = para;
977}

Referenced by adjust_para_y(), and ME_WrapMarkedParagraphs().

◆ ME_MaximizeSplit()

static ME_DisplayItem * ME_MaximizeSplit ( ME_WrapContext wc,
ME_DisplayItem p,
int  i 
)
static

Definition at line 456 of file wrap.c.

457{
458 ME_DisplayItem *pp, *piter = p;
459 int j;
460 if (!i)
461 return NULL;
462 j = reverse_find_non_whitespace( get_text( &p->member.run, 0 ), i);
463 if (j>0) {
464 pp = split_run_extents(wc, piter, j);
465 wc->pt.x += piter->member.run.nWidth;
466 return pp;
467 }
468 else
469 {
470 pp = piter;
471 /* omit all spaces before split point */
472 while(piter != wc->pRowStart)
473 {
474 piter = ME_FindItemBack(piter, diRun);
475 if (piter->member.run.nFlags & MERF_WHITESPACE)
476 {
477 pp = piter;
478 continue;
479 }
480 if (piter->member.run.nFlags & MERF_ENDWHITE)
481 {
483 piter->member.run.len );
484 pp = split_run_extents(wc, piter, i);
485 wc->pt = pp->member.run.pt;
486 return pp;
487 }
488 /* this run is the end of spaces, so the run edge is a good point to split */
489 wc->pt = pp->member.run.pt;
490 wc->bOverflown = TRUE;
491 TRACE("Split point is: %s|%s\n", debugstr_run( &piter->member.run ), debugstr_run( &pp->member.run ));
492 return pp;
493 }
494 wc->pt = piter->member.run.pt;
495 return piter;
496 }
497}
#define MERF_ENDWHITE
Definition: editstr.h:118
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 GLint GLint j
Definition: glfuncs.h:250
POINT pt
Definition: editstr.h:167
static int reverse_find_non_whitespace(const WCHAR *s, int start)
Definition: wrap.c:437
static ME_DisplayItem * split_run_extents(ME_WrapContext *wc, ME_DisplayItem *item, int nVChar)
Definition: wrap.c:131

Referenced by ME_SplitByBacktracking().

◆ ME_PrepareParagraphForWrapping()

static void ME_PrepareParagraphForWrapping ( ME_TextEditor editor,
ME_Context c,
ME_DisplayItem tp 
)
static

Definition at line 730 of file wrap.c.

730 {
732
733 tp->member.para.nWidth = 0;
734 /* remove row start items as they will be reinserted by the
735 * paragraph wrapper anyway */
736 editor->total_rows -= tp->member.para.nRows;
737 tp->member.para.nRows = 0;
738 for (p = tp->next; p != tp->member.para.next_para; p = p->next) {
739 if (p->type == diStartRow) {
740 ME_DisplayItem *pRow = p;
741 p = p->prev;
742 ME_Remove(pRow);
744 }
745 }
746 /* join runs that can be joined */
747 for (p = tp->next; p != tp->member.para.next_para; p = p->next) {
748 assert(p->type != diStartRow); /* should have been deleted above */
749 if (p->type == diRun) {
750 while (p->next->type == diRun && /* FIXME */
751 ME_CanJoinRuns(&p->member.run, &p->next->member.run)) {
752 ME_JoinRuns(c->editor, p);
753 }
754 }
755 }
756}
_In_ uint64_t _In_ uint64_t _In_ uint64_t _In_opt_ traverse_ptr * tp
Definition: btrfs.c:2996
void ME_JoinRuns(ME_TextEditor *editor, ME_DisplayItem *p) DECLSPEC_HIDDEN
Definition: run.c:229
void ME_DestroyDisplayItem(ME_DisplayItem *item) DECLSPEC_HIDDEN
Definition: list.c:160
void ME_Remove(ME_DisplayItem *diWhere) DECLSPEC_HIDDEN
Definition: list.c:35
BOOL ME_CanJoinRuns(const ME_Run *run1, const ME_Run *run2) DECLSPEC_HIDDEN
Definition: run.c:35

Referenced by ME_WrapTextParagraph().

◆ ME_SendRequestResize()

void ME_SendRequestResize ( ME_TextEditor editor,
BOOL  force 
)

Definition at line 1198 of file wrap.c.

1199{
1200 if (editor->nEventMask & ENM_REQUESTRESIZE)
1201 {
1202 RECT rc;
1203
1204 ITextHost_TxGetClientRect(editor->texthost, &rc);
1205
1206 if (force || rc.bottom != editor->nTotalLength)
1207 {
1209
1210 info.nmhdr.hwndFrom = NULL;
1211 info.nmhdr.idFrom = 0;
1212 info.nmhdr.code = EN_REQUESTRESIZE;
1213 info.rc = rc;
1214 info.rc.right = editor->nTotalWidth;
1215 info.rc.bottom = editor->nTotalLength;
1216
1217 editor->nEventMask &= ~ENM_REQUESTRESIZE;
1218 ITextHost_TxNotify(editor->texthost, info.nmhdr.code, &info);
1219 editor->nEventMask |= ENM_REQUESTRESIZE;
1220 }
1221 }
1222}
#define ITextHost_TxNotify(This, a, b)
Definition: editor.h:322
#define ITextHost_TxGetClientRect(This, a)
Definition: editor.h:308
#define EN_REQUESTRESIZE
Definition: richedit.h:192
#define ENM_REQUESTRESIZE
Definition: richedit.h:477

Referenced by ME_HandleMessage(), ME_KeyDown(), ME_PaintContent(), and ME_StreamIn().

◆ ME_SplitByBacktracking()

static ME_DisplayItem * ME_SplitByBacktracking ( ME_WrapContext wc,
ME_DisplayItem p,
int  loc 
)
static

Definition at line 499 of file wrap.c.

500{
501 ME_DisplayItem *piter = p, *pp;
502 int i, idesp, len;
503 ME_Run *run = &p->member.run;
504
505 idesp = i = find_split_point( wc->context, loc, run );
506 len = run->len;
507 assert(len>0);
508 assert(i<len);
509 if (i) {
510 /* don't split words */
511 i = reverse_find_whitespace( get_text( run, 0 ), i );
512 pp = ME_MaximizeSplit(wc, p, i);
513 if (pp)
514 return pp;
515 }
516 TRACE("Must backtrack to split at: %s\n", debugstr_run( &p->member.run ));
517 if (wc->pLastSplittableRun)
518 {
520 {
521 wc->pt = wc->pLastSplittableRun->member.run.pt;
522 return wc->pLastSplittableRun;
523 }
525 {
526 /* the following two lines are just to check if we forgot to call UpdateRunFlags earlier,
527 they serve no other purpose */
530
531 piter = wc->pLastSplittableRun;
532 run = &piter->member.run;
533 len = run->len;
534 /* don't split words */
535 i = reverse_find_whitespace( get_text( run, 0 ), len );
536 if (i == len)
538 if (i) {
539 ME_DisplayItem *piter2 = split_run_extents(wc, piter, i);
540 wc->pt = piter2->member.run.pt;
541 return piter2;
542 }
543 /* splittable = must have whitespaces */
544 assert(0 == "Splittable, but no whitespaces");
545 }
546 else
547 {
548 /* restart from the first run beginning with spaces */
549 wc->pt = wc->pLastSplittableRun->member.run.pt;
550 return wc->pLastSplittableRun;
551 }
552 }
553 TRACE("Backtracking failed, trying desperate: %s\n", debugstr_run( &p->member.run ));
554 /* OK, no better idea, so assume we MAY split words if we can split at all*/
555 if (idesp)
556 return split_run_extents(wc, piter, idesp);
557 else
558 if (wc->pRowStart && piter != wc->pRowStart)
559 {
560 /* don't need to break current run, because it's possible to split
561 before this run */
562 wc->bOverflown = TRUE;
563 return piter;
564 }
565 else
566 {
567 /* split point inside first character - no choice but split after that char */
568 if (len != 1) {
569 /* the run is more than 1 char, so we may split */
570 return split_run_extents(wc, piter, 1);
571 }
572 /* the run is one char, can't split it */
573 return piter;
574 }
575}
void ME_UpdateRunFlags(ME_TextEditor *editor, ME_Run *run) DECLSPEC_HIDDEN
Definition: run.c:413
#define MERF_TAB
Definition: editstr.h:107
#define MERF_SPLITTABLE
Definition: editstr.h:114
static int reverse_find_whitespace(const WCHAR *s, int start)
Definition: wrap.c:447
static ME_DisplayItem * ME_MaximizeSplit(ME_WrapContext *wc, ME_DisplayItem *p, int i)
Definition: wrap.c:456
static int find_split_point(ME_Context *c, int cx, ME_Run *run)
Definition: wrap.c:174

Referenced by ME_WrapHandleRun().

◆ ME_WrapEndParagraph()

static void ME_WrapEndParagraph ( ME_WrapContext wc,
ME_DisplayItem p 
)
static

Definition at line 384 of file wrap.c.

385{
386 ME_DisplayItem *para = wc->pPara;
387 PARAFORMAT2 *pFmt = &para->member.para.fmt;
388 if (wc->pRowStart)
389 ME_InsertRowStart(wc, p);
390 if (wc->context->editor->bEmulateVersion10 && /* v1.0 - 3.0 */
391 pFmt->dwMask & PFM_TABLE && pFmt->wEffects & PFE_TABLE)
392 {
393 /* ME_BeginRow was called an extra time for the paragraph, and it shifts the
394 * text down by one pixel for the border, so fix up the wrap context. */
395 wc->pt.y--;
396 }
397
398 /*
399 p = para->next;
400 while(p) {
401 if (p->type == diParagraph || p->type == diTextEnd)
402 return;
403 if (p->type == diRun)
404 {
405 ME_Run *run = &p->member.run;
406 TRACE("%s - (%d, %d)\n", debugstr_run(run), run->pt.x, run->pt.y);
407 }
408 p = p->next;
409 }
410 */
411}
static void ME_InsertRowStart(ME_WrapContext *wc, const ME_DisplayItem *pEnd)
Definition: wrap.c:295

Referenced by ME_WrapTextParagraph().

◆ ME_WrapHandleRun()

static ME_DisplayItem * ME_WrapHandleRun ( ME_WrapContext wc,
ME_DisplayItem p 
)
static

Definition at line 577 of file wrap.c.

578{
579 ME_DisplayItem *pp;
580 ME_Run *run;
581 int len;
582
583 assert(p->type == diRun);
584 if (!wc->pRowStart)
585 wc->pRowStart = p;
586 run = &p->member.run;
587 run->pt.x = wc->pt.x;
588 run->pt.y = wc->pt.y;
589 ME_WrapSizeRun(wc, p);
590 len = run->len;
591
592 if (wc->bOverflown) /* just skipping final whitespaces */
593 {
594 /* End paragraph run can't overflow to the next line by itself. */
595 if (run->nFlags & MERF_ENDPARA)
596 return p->next;
597
598 if (run->nFlags & MERF_WHITESPACE) {
599 wc->pt.x += run->nWidth;
600 /* skip runs consisting of only whitespaces */
601 return p->next;
602 }
603
604 if (run->nFlags & MERF_STARTWHITE) {
605 /* try to split the run at the first non-white char */
606 int black;
607 black = find_non_whitespace( get_text( run, 0 ), run->len, 0 );
608 if (black) {
609 wc->bOverflown = FALSE;
610 pp = split_run_extents(wc, p, black);
612 wc->nRow ? wc->nLeftMargin : wc->nFirstMargin,
613 &pp->member.run);
614 ME_InsertRowStart(wc, pp);
615 return pp;
616 }
617 }
618 /* black run: the row goes from pRowStart to the previous run */
619 ME_InsertRowStart(wc, p);
620 return p;
621 }
622 /* simply end the current row and move on to next one */
623 if (run->nFlags & MERF_ENDROW)
624 {
625 p = p->next;
626 ME_InsertRowStart(wc, p);
627 return p;
628 }
629
630 /* will current run fit? */
631 if (wc->bWordWrap &&
632 wc->pt.x + run->nWidth - wc->context->pt.x > wc->nAvailWidth)
633 {
634 int loc = wc->context->pt.x + wc->nAvailWidth - wc->pt.x;
635 /* total white run or end para */
636 if (run->nFlags & (MERF_WHITESPACE | MERF_ENDPARA)) {
637 /* let the overflow logic handle it */
638 wc->bOverflown = TRUE;
639 return p;
640 }
641 /* TAB: we can split before */
642 if (run->nFlags & MERF_TAB) {
643 wc->bOverflown = TRUE;
644 if (wc->pRowStart == p)
645 /* Don't split before the start of the run, or we will get an
646 * endless loop. */
647 return p->next;
648 else
649 return p;
650 }
651 /* graphics: we can split before, if run's width is smaller than row's width */
652 if ((run->nFlags & MERF_GRAPHICS) && run->nWidth <= wc->nAvailWidth) {
653 wc->bOverflown = TRUE;
654 return p;
655 }
656 /* can we separate out the last spaces ? (to use overflow logic later) */
657 if (run->nFlags & MERF_ENDWHITE)
658 {
659 /* we aren't sure if it's *really* necessary, it's a good start however */
660 int black = reverse_find_non_whitespace( get_text( run, 0 ), len );
661 split_run_extents(wc, p, black);
662 /* handle both parts again */
663 return p;
664 }
665 /* determine the split point by backtracking */
666 pp = ME_SplitByBacktracking(wc, p, loc);
667 if (pp == wc->pRowStart)
668 {
669 if (run->nFlags & MERF_STARTWHITE)
670 {
671 /* We had only spaces so far, so we must be on the first line of the
672 * paragraph (or the first line after MERF_ENDROW forced the line
673 * break within the paragraph), since no other lines of the paragraph
674 * start with spaces. */
675
676 /* The lines will only contain spaces, and the rest of the run will
677 * overflow onto the next line. */
678 wc->bOverflown = TRUE;
679 return p;
680 }
681 /* Couldn't split the first run, possible because we have a large font
682 * with a single character that caused an overflow.
683 */
684 wc->pt.x += run->nWidth;
685 return p->next;
686 }
687 if (p != pp) /* found a suitable split point */
688 {
689 wc->bOverflown = TRUE;
690 return pp;
691 }
692 /* we detected that it's best to split on start of this run */
693 if (wc->bOverflown)
694 return pp;
695 ERR("failure!\n");
696 /* not found anything - writing over margins is the only option left */
697 }
698 if ((run->nFlags & (MERF_SPLITTABLE | MERF_STARTWHITE))
699 || ((run->nFlags & (MERF_GRAPHICS|MERF_TAB)) && (p != wc->pRowStart)))
700 {
701 wc->pLastSplittableRun = p;
702 }
703 wc->pt.x += run->nWidth;
704 return p->next;
705}
#define ERR(fmt,...)
Definition: debug.h:110
#define MERF_STARTWHITE
Definition: editstr.h:116
#define MERF_ENDROW
Definition: editstr.h:124
struct define * next
Definition: compiler.c:65
static void calc_run_extent(ME_Context *c, const ME_Paragraph *para, int startx, ME_Run *run)
Definition: wrap.c:115
static void ME_WrapSizeRun(ME_WrapContext *wc, ME_DisplayItem *p)
Definition: wrap.c:413
static ME_DisplayItem * ME_SplitByBacktracking(ME_WrapContext *wc, ME_DisplayItem *p, int loc)
Definition: wrap.c:499
static int find_non_whitespace(const WCHAR *s, int len, int start)
Definition: wrap.c:424

Referenced by ME_WrapTextParagraph().

◆ ME_WrapMarkedParagraphs()

BOOL ME_WrapMarkedParagraphs ( ME_TextEditor editor)

Definition at line 1093 of file wrap.c.

1094{
1096 ME_Context c;
1097 int totalWidth = editor->nTotalWidth, diff = 0, prev_width;
1098 ME_DisplayItem *repaint_start = NULL, *repaint_end = NULL;
1099 ME_Paragraph *para;
1100
1101 if (!editor->first_marked_para)
1102 return FALSE;
1103
1104 ME_InitContext(&c, editor, ITextHost_TxGetDC(editor->texthost));
1105
1106 item = editor->first_marked_para;
1107 c.pt = item->member.para.pt;
1108 while (item != editor->pBuffer->pLast)
1109 {
1110 assert(item->type == diParagraph);
1111
1112 prev_width = item->member.para.nWidth;
1113 ME_WrapTextParagraph(editor, &c, item);
1114 if (prev_width == totalWidth && item->member.para.nWidth < totalWidth)
1115 totalWidth = get_total_width(editor);
1116 else
1117 totalWidth = max(totalWidth, item->member.para.nWidth);
1118
1119 if (!item->member.para.nCharOfs)
1120 ME_MarkRepaintEnd(item->member.para.prev_para, &repaint_start, &repaint_end);
1121 ME_MarkRepaintEnd(item, &repaint_start, &repaint_end);
1122 adjust_para_y(item, &c, repaint_start, repaint_end);
1123
1124 if (item->member.para.next_para)
1125 {
1126 diff = c.pt.y - item->member.para.next_para->member.para.pt.y;
1127 if (diff)
1128 {
1129 para = &item->member.para;
1130 while (para->next_para && para != &item->member.para.next_marked->member.para &&
1131 para != &editor->pBuffer->pLast->member.para)
1132 {
1133 ME_MarkRepaintEnd(para->next_para, &repaint_start, &repaint_end);
1134 para->next_para->member.para.pt.y = c.pt.y;
1135 adjust_para_y(para->next_para, &c, repaint_start, repaint_end);
1136 para = &para->next_para->member.para;
1137 }
1138 }
1139 }
1140 if (item->member.para.next_marked)
1141 {
1142 ME_DisplayItem *rem = item;
1143 item = item->member.para.next_marked;
1144 remove_marked_para(editor, rem);
1145 }
1146 else
1147 {
1148 remove_marked_para(editor, item);
1149 item = editor->pBuffer->pLast;
1150 }
1151 c.pt.y = item->member.para.pt.y;
1152 }
1153 editor->sizeWindow.cx = c.rcView.right-c.rcView.left;
1154 editor->sizeWindow.cy = c.rcView.bottom-c.rcView.top;
1155
1156 editor->nTotalLength = c.pt.y;
1157 editor->nTotalWidth = totalWidth;
1158 editor->pBuffer->pLast->member.para.pt.x = 0;
1159 editor->pBuffer->pLast->member.para.pt.y = c.pt.y;
1160
1162
1163 if (repaint_start || editor->nTotalLength < editor->nLastTotalLength)
1164 ME_InvalidateParagraphRange(editor, repaint_start, repaint_end);
1165 return !!repaint_start;
1166}
int get_total_width(ME_TextEditor *editor) DECLSPEC_HIDDEN
Definition: para.c:64
void remove_marked_para(ME_TextEditor *editor, ME_DisplayItem *para) DECLSPEC_HIDDEN
Definition: para.c:82
struct tagME_DisplayItem * next_para
Definition: editstr.h:217
ME_DisplayItem * pLast
Definition: editstr.h:268
ME_DisplayItem * first_marked_para
Definition: editstr.h:433
ME_TextBuffer * pBuffer
Definition: editstr.h:386
LONG cx
Definition: windef.h:334
LONG cy
Definition: windef.h:335
static void adjust_para_y(ME_DisplayItem *item, ME_Context *c, ME_DisplayItem *repaint_start, ME_DisplayItem *repaint_end)
Definition: wrap.c:979
void ME_InvalidateParagraphRange(ME_TextEditor *editor, ME_DisplayItem *start_para, ME_DisplayItem *last_para)
Definition: wrap.c:1168
static void ME_WrapTextParagraph(ME_TextEditor *editor, ME_Context *c, ME_DisplayItem *tp)
Definition: wrap.c:868

Referenced by handle_EM_SETCHARFORMAT(), ME_HandleMessage(), ME_InvalidateSelection(), ME_Repaint(), ME_RewrapRepaint(), ME_SelectOrInsertNextCell(), ME_UpdateRepaint(), ME_UpdateScrollBar(), and ME_WmCreate().

◆ ME_WrapSizeRun()

static void ME_WrapSizeRun ( ME_WrapContext wc,
ME_DisplayItem p 
)
static

Definition at line 413 of file wrap.c.

414{
415 /* FIXME compose style (out of character and paragraph styles) here */
416
417 ME_UpdateRunFlags(wc->context->editor, &p->member.run);
418
420 wc->nRow ? wc->nLeftMargin : wc->nFirstMargin, &p->member.run);
421}

Referenced by ME_WrapHandleRun().

◆ ME_WrapTextParagraph()

static void ME_WrapTextParagraph ( ME_TextEditor editor,
ME_Context c,
ME_DisplayItem tp 
)
static

Definition at line 868 of file wrap.c.

868 {
871 int border = 0;
872 int linespace = 0;
873 PARAFORMAT2 *pFmt;
874
875 assert(tp->type == diParagraph);
876 if (!(tp->member.para.nFlags & MEPF_REWRAP)) {
877 return;
878 }
880
881 /* Calculate paragraph numbering label */
882 para_num_init( c, &tp->member.para );
883
884 /* For now treating all non-password text as complex for better testing */
885 if (!c->editor->cPasswordMask /* &&
886 ScriptIsComplex( tp->member.para.text->szData, tp->member.para.text->nLen, SIC_COMPLEX ) == S_OK */)
887 {
888 if (SUCCEEDED( itemize_para( c, tp ) ))
889 shape_para( c, tp );
890 }
891
892 pFmt = &tp->member.para.fmt;
893
894 wc.context = c;
895 wc.pPara = tp;
896/* wc.para_style = tp->member.para.style; */
897 wc.style = NULL;
898 wc.nParaNumOffset = 0;
899 if (tp->member.para.nFlags & MEPF_ROWEND) {
900 wc.nFirstMargin = wc.nLeftMargin = wc.nRightMargin = 0;
901 } else {
902 int dxStartIndent = pFmt->dxStartIndent;
903 if (tp->member.para.pCell) {
904 dxStartIndent += ME_GetTableRowEnd(tp)->member.para.fmt.dxOffset;
905 }
906 wc.nLeftMargin = ME_twips2pointsX(c, dxStartIndent + pFmt->dxOffset);
907 wc.nFirstMargin = ME_twips2pointsX(c, dxStartIndent);
908 if (pFmt->wNumbering)
909 {
911 dxStartIndent = max( ME_twips2pointsX(c, pFmt->wNumberingTab),
912 tp->member.para.para_num.width );
913 wc.nFirstMargin += dxStartIndent;
914 }
916
917 if (wc.nFirstMargin < 0)
918 wc.nFirstMargin = 0;
919 if (wc.nLeftMargin < 0)
920 wc.nLeftMargin = 0;
921 }
922 if (c->editor->bEmulateVersion10 && /* v1.0 - 3.0 */
923 pFmt->dwMask & PFM_TABLE && pFmt->wEffects & PFE_TABLE)
924 {
925 wc.nFirstMargin += ME_twips2pointsX(c, pFmt->dxOffset * 2);
926 }
927 wc.nRow = 0;
928 wc.pt.y = 0;
929 if (pFmt->dwMask & PFM_SPACEBEFORE)
930 wc.pt.y += ME_twips2pointsY(c, pFmt->dySpaceBefore);
931 if (!(pFmt->dwMask & PFM_TABLE && pFmt->wEffects & PFE_TABLE) &&
932 pFmt->dwMask & PFM_BORDER)
933 {
934 border = ME_GetParaBorderWidth(c, tp->member.para.fmt.wBorders);
935 if (pFmt->wBorders & 1) {
936 wc.nFirstMargin += border;
937 wc.nLeftMargin += border;
938 }
939 if (pFmt->wBorders & 2)
940 wc.nRightMargin -= border;
941 if (pFmt->wBorders & 4)
942 wc.pt.y += border;
943 }
944
945 linespace = ME_GetParaLineSpace(c, &tp->member.para);
946
947 ME_BeginRow(&wc);
948 for (p = tp->next; p!=tp->member.para.next_para; ) {
949 assert(p->type != diStartRow);
950 if (p->type == diRun) {
951 p = ME_WrapHandleRun(&wc, p);
952 }
953 else p = p->next;
954 if (wc.nRow && p == wc.pRowStart)
955 wc.pt.y += linespace;
956 }
958 if (!(pFmt->dwMask & PFM_TABLE && pFmt->wEffects & PFE_TABLE) &&
959 (pFmt->dwMask & PFM_BORDER) && (pFmt->wBorders & 8))
960 wc.pt.y += border;
961 if (tp->member.para.fmt.dwMask & PFM_SPACEAFTER)
962 wc.pt.y += ME_twips2pointsY(c, pFmt->dySpaceAfter);
963
964 tp->member.para.nFlags &= ~MEPF_REWRAP;
965 tp->member.para.nHeight = wc.pt.y;
966 tp->member.para.nRows = wc.nRow;
967 editor->total_rows += wc.nRow;
968}
int ME_GetParaBorderWidth(const ME_Context *c, int flags) DECLSPEC_HIDDEN
Definition: paint.c:529
void para_num_init(ME_Context *c, ME_Paragraph *para) DECLSPEC_HIDDEN
Definition: para.c:395
#define MEPF_REWRAP
Definition: editstr.h:141
GLint GLint GLsizei GLsizei GLsizei GLint border
Definition: gl.h:1546
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define PFM_SPACEBEFORE
Definition: richedit.h:847
#define PFM_BORDER
Definition: richedit.h:851
#define PFM_SPACEAFTER
Definition: richedit.h:848
LONG dySpaceBefore
Definition: richedit.h:676
LONG dxRightIndent
Definition: richedit.h:671
LONG dySpaceAfter
Definition: richedit.h:676
LONG dxOffset
Definition: richedit.h:672
WORD wBorders
Definition: richedit.h:681
WORD wNumberingTab
Definition: richedit.h:680
ME_Style * style
Definition: wrap.c:37
static int ME_GetParaLineSpace(ME_Context *c, ME_Paragraph *para)
Definition: wrap.c:707
static void ME_WrapEndParagraph(ME_WrapContext *wc, ME_DisplayItem *p)
Definition: wrap.c:384
static HRESULT itemize_para(ME_Context *c, ME_DisplayItem *p)
Definition: wrap.c:758
static void ME_PrepareParagraphForWrapping(ME_TextEditor *editor, ME_Context *c, ME_DisplayItem *tp)
Definition: wrap.c:730
static HRESULT shape_para(ME_Context *c, ME_DisplayItem *p)
Definition: wrap.c:847
static ME_DisplayItem * ME_WrapHandleRun(ME_WrapContext *wc, ME_DisplayItem *p)
Definition: wrap.c:577

Referenced by ME_WrapMarkedParagraphs().

◆ reverse_find_non_whitespace()

static int reverse_find_non_whitespace ( const WCHAR s,
int  start 
)
static

Definition at line 437 of file wrap.c.

438{
439 int i;
440 for (i = start; i > 0 && ME_IsWSpace( s[i - 1] ); i--)
441 ;
442
443 return i;
444}

Referenced by ME_MaximizeSplit(), ME_SplitByBacktracking(), and ME_WrapHandleRun().

◆ reverse_find_whitespace()

static int reverse_find_whitespace ( const WCHAR s,
int  start 
)
static

Definition at line 447 of file wrap.c.

448{
449 int i;
450 for (i = start; i > 0 && !ME_IsWSpace( s[i - 1] ); i--)
451 ;
452
453 return i;
454}

Referenced by ME_SplitByBacktracking().

◆ shape_para()

static HRESULT shape_para ( ME_Context c,
ME_DisplayItem p 
)
static

Definition at line 847 of file wrap.c.

848{
849 ME_DisplayItem *di;
850 ME_Run *run;
851 HRESULT hr;
852
853 for (di = p->next; di != p->member.para.next_para; di = di->next)
854 {
855 if (di->type != diRun) continue;
856 run = &di->member.run;
857
858 hr = shape_run( c, run );
859 if (FAILED( hr ))
860 {
861 run->para->nFlags &= ~MEPF_COMPLEX;
862 return hr;
863 }
864 }
865 return hr;
866}
struct tagME_Paragraph * para
Definition: editstr.h:161
static HRESULT shape_run(ME_Context *c, ME_Run *run)
Definition: wrap.c:65

Referenced by ME_WrapTextParagraph().

◆ shape_run()

static HRESULT shape_run ( ME_Context c,
ME_Run run 
)
static

Definition at line 65 of file wrap.c.

66{
67 HRESULT hr;
68 int i;
69
70 if (!run->glyphs)
71 {
72 run->max_glyphs = 1.5 * run->len + 16; /* This is suggested in the uniscribe documentation */
73 run->max_glyphs = (run->max_glyphs + 7) & ~7; /* Keep alignment simple */
75 }
76
77 if (run->max_clusters < run->len)
78 {
79 heap_free( run->clusters );
80 run->max_clusters = run->len * 2;
81 run->clusters = heap_alloc( run->max_clusters * sizeof(WORD) );
82 }
83
84 select_style( c, run->style );
85 while (1)
86 {
87 hr = ScriptShape( c->hDC, &run->style->script_cache, get_text( run, 0 ), run->len, run->max_glyphs,
88 &run->script_analysis, run->glyphs, run->clusters, run->vis_attrs, &run->num_glyphs );
89 if (hr != E_OUTOFMEMORY) break;
90 if (run->max_glyphs > 10 * run->len) break; /* something has clearly gone wrong */
91 run->max_glyphs *= 2;
93 }
94
95 if (SUCCEEDED(hr))
96 hr = ScriptPlace( c->hDC, &run->style->script_cache, run->glyphs, run->num_glyphs, run->vis_attrs,
97 &run->script_analysis, run->advances, run->offsets, NULL );
98
99 if (SUCCEEDED(hr))
100 {
101 for (i = 0, run->nWidth = 0; i < run->num_glyphs; i++)
102 run->nWidth += run->advances[i];
103 }
104
105 return hr;
106}
HRESULT WINAPI ScriptPlace(HDC hdc, SCRIPT_CACHE *psc, const WORD *pwGlyphs, int cGlyphs, const SCRIPT_VISATTR *psva, SCRIPT_ANALYSIS *psa, int *piAdvance, GOFFSET *pGoffset, ABC *pABC)
Definition: usp10.c:3510
HRESULT WINAPI ScriptShape(HDC hdc, SCRIPT_CACHE *psc, const WCHAR *pwcChars, int cChars, int cMaxGlyphs, SCRIPT_ANALYSIS *psa, WORD *pwOutGlyphs, WORD *pwLogClust, SCRIPT_VISATTR *psva, int *pcGlyphs)
Definition: usp10.c:3321
void select_style(ME_Context *c, ME_Style *s) DECLSPEC_HIDDEN
Definition: style.c:369
int num_glyphs
Definition: editstr.h:171
int max_clusters
Definition: editstr.h:176
ME_Style * style
Definition: editstr.h:160
WORD * clusters
Definition: editstr.h:177
SCRIPT_CACHE script_cache
Definition: editstr.h:78
static BOOL get_run_glyph_buffers(ME_Run *run)
Definition: wrap.c:52

Referenced by shape_para(), and split_run_extents().

◆ split_run_extents()

static ME_DisplayItem * split_run_extents ( ME_WrapContext wc,
ME_DisplayItem item,
int  nVChar 
)
static

Definition at line 131 of file wrap.c.

132{
133 ME_TextEditor *editor = wc->context->editor;
134 ME_Run *run, *run2;
135 ME_Paragraph *para = &wc->pPara->member.para;
136 ME_Cursor cursor = {wc->pPara, item, nVChar};
137
138 assert(item->member.run.nCharOfs != -1);
139 ME_CheckCharOffsets(editor);
140
141 run = &item->member.run;
142
143 TRACE("Before split: %s(%d, %d)\n", debugstr_run( run ),
144 run->pt.x, run->pt.y);
145
146 ME_SplitRunSimple(editor, &cursor);
147
148 run2 = &cursor.pRun->member.run;
149 run2->script_analysis = run->script_analysis;
150
151 shape_run( wc->context, run );
152 shape_run( wc->context, run2 );
153 calc_run_extent(wc->context, para, wc->nRow ? wc->nLeftMargin : wc->nFirstMargin, run);
154
155 run2->pt.x = run->pt.x+run->nWidth;
156 run2->pt.y = run->pt.y;
157
158 ME_CheckCharOffsets(editor);
159
160 TRACE("After split: %s(%d, %d), %s(%d, %d)\n",
161 debugstr_run( run ), run->pt.x, run->pt.y,
162 debugstr_run( run2 ), run2->pt.x, run2->pt.y);
163
164 return cursor.pRun;
165}
void ME_CheckCharOffsets(ME_TextEditor *editor) DECLSPEC_HIDDEN
Definition: run.c:101

Referenced by ME_MaximizeSplit(), ME_SplitByBacktracking(), and ME_WrapHandleRun().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( richedit  )