Sweden-Number/dlls/riched20/row.c

139 lines
3.9 KiB
C

/*
* RichEdit - Operations on rows of text (rows are recreated during
* wrapping and are used for displaying the document, they don't keep any
* true document content; delete all rows, rewrap all paragraphs and
* you get them back).
*
* Copyright 2004 by Krzysztof Foltman
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "editor.h"
ME_Row *row_next( ME_Row *row )
{
ME_DisplayItem *item;
item = ME_FindItemFwd( row_get_di( row ), diStartRowOrParagraphOrEnd );
if (!item || item->type != diStartRow) return NULL;
return &item->member.row;
}
ME_Run *row_first_run( ME_Row *row )
{
ME_DisplayItem *item;
item = ME_FindItemFwd( row_get_di( row ), diRunOrStartRow );
assert( item->type == diRun );
return &item->member.run;
}
ME_Run *row_next_run( ME_Row *row, ME_Run *run )
{
ME_DisplayItem *item;
assert( row == &ME_FindItemBack( run_get_di( run ), diStartRow )->member.row );
item = ME_FindItemFwd( run_get_di( run ), diRunOrStartRow );
if (!item || item->type == diStartRow) return NULL;
return &item->member.run;
}
ME_Row *row_from_cursor( ME_Cursor *cursor )
{
ME_DisplayItem *item;
item = ME_FindItemBack( cursor->pRun, diStartRow );
return &item->member.row;
}
void row_first_cursor( ME_Row *row, ME_Cursor *cursor )
{
ME_DisplayItem *item;
item = ME_FindItemFwd( row_get_di( row ), diRun );
cursor->pRun = item;
cursor->pPara = para_get_di( cursor->pRun->member.run.para );
cursor->nOffset = 0;
}
void row_end_cursor( ME_Row *row, ME_Cursor *cursor, BOOL include_eop )
{
ME_DisplayItem *item, *run;
item = ME_FindItemFwd( row_get_di( row ), diStartRowOrParagraphOrEnd );
run = ME_FindItemBack( item, diRun );
cursor->pRun = run;
cursor->pPara = para_get_di( cursor->pRun->member.run.para );
cursor->nOffset = (item->type == diStartRow || include_eop) ? cursor->pRun->member.run.len : 0;
}
ME_DisplayItem *ME_RowStart(ME_DisplayItem *item) {
return ME_FindItemBackOrHere(item, diStartRow);
}
ME_Row *row_from_row_number( ME_TextEditor *editor, int row_num )
{
ME_Paragraph *para = editor_first_para( editor );
ME_Row *row;
int count = 0;
while (para_next( para ) && count + para->nRows <= row_num)
{
count += para->nRows;
para = para_next( para );
}
if (!para_next( para )) return NULL;
for (row = para_first_row( para ); row && count < row_num; count++)
row = row_next( row );
return row;
}
int
ME_RowNumberFromCharOfs(ME_TextEditor *editor, int nOfs)
{
ME_DisplayItem *item = ME_FindItemFwd(editor->pBuffer->pFirst, diParagraph);
int nRow = 0;
while (item->type == diParagraph &&
item->member.para.next_para->member.para.nCharOfs <= nOfs)
{
nRow += item->member.para.nRows;
item = item->member.para.next_para;
}
if (item->type == diParagraph)
{
ME_DisplayItem *next_para = item->member.para.next_para;
nOfs -= item->member.para.nCharOfs;
item = ME_FindItemFwd(item, diRun);
while ((item = ME_FindItemFwd(item, diStartRowOrParagraph)) != NULL)
{
if (item == next_para)
break;
item = ME_FindItemFwd(item, diRun);
if (item->member.run.nCharOfs > nOfs)
break;
nRow++;
}
}
return nRow;
}