The website "djvu-soft.narod.ru." is not registered with uCoz.
If you are absolutely sure your website must be here,
please contact our Support Team.
If you were searching for something on the Internet and ended up here, try again:

About uCoz web-service

Community

Legal information

Описание библиотеки CED - контейнера для работы с ed файлами

Вернуться к разделу "OpenOCR".


Описание библиотеки CED - контейнера для работы с ed файлами

Библиотека выполнена в виде dll файла(ced.dll), заголовочные файлы ced_struc.h 
или ced.h. ced_struc.h следует включать в программы на C++, он содержит описатели
классов, рассматриваемых ниже. ced.h - несколько урезанная версия
для включения в C-код, не содержит описателей классов, но содержит С-функции,
работающие с Handl'ами, позволяющие работать с деревом(впрочем эти функции 
есть и в ced_struct). Не следует включать эти два хедера одновременно.

Для работы требует наличия и предварительной инициализации модуля CFIO.

Библиотека позволяет работать с ed не напрямую, что неприемлемо по соображениям 
совместимости с будующими версиями, а посредством заполнения древовидной
структуры, которая в дальнейшем может быть записана в файл, либо прочитана 
из него. Впрочем, желающие читать и писать данные напрямик в ed тоже не
останутся без внимания - для них существует интерфейс низкого уровня, который,
однако, позволяет добиться требуемой независимости программного кода
он версии ed формата. Повторюсь: вся запись в ed должна осуществляться исключительно 
через библиотеку. В противном случае никто не гарантирует, что ваш код будет
работать с будущими версиями ed-файлов.

Все желающие могут ознакомиться с бинарным ed-форматом, он описан в файле
ed-diskr.txt. По всем вопросам обращаться dukei@com2com.ru 

                                                     7.12.98  Артем Боженов

		Интерфейс высокого уровня.

Для того, чтобы записать/читать файл, используется довольно хитрая
(но очевидная, на мой взгляд) иерархическая структура. Она несет в 
себе всю информацию по форматированию текста, которая может быть записана 
в рамках стандартного набора команд ed. Также в ней заложена возможность
читать и сохранять прочую информацию, которую пользователь библиотеки
сочтет нужной. Структура в своих узлах имеет представителей следующих С-классов:
CEDPage - описатель страницы, CEDSection - описатель раздела(секции),
CEDParagraph - описатель параграфа, CEDLine - строки, CEDChar - символа.
В настоящий момент в ed-файле может находиться на более 1й страницы, так
что и класс CEDPage присутствует здесь в единственном экземпляре.
Под разделом понимается то же сомое, что и при рассотрении rtf формата,
т.е. горизонтальный сегмент текста, имеющий собственное количество
колонок и свои отступы от краев бумаги.
Взаимоотношения между представителями классов изображены на диаграмме:

                CEDPage
                 ¦                  
     -------T----+--------T-------------T------¬     
     v      v             v             v      v  
CEDSection0-CEDSection1-CEDSection2-CEDSection3-CEDSection4     
       ¦     ¦                                           ¦
       ¦     L--------------¬                            ¦ 
       v                    v                            v  
CEDParagraph0-CEDParagraph1-CEDParagraph2-CEDParagraph3-CEDParagraph4    
              ¦                                          ¦
    -----------                                    -------      
    v                                              v
CEDLine0-CEDLine1-CEDLine2-CEDLine3-CEDLine4-CEDLine5     
    ¦        ¦                                     ¦
    ¦        L-----------------¬                   L----¬
    v                          v                        v
CEDChar0-CEDChar1-CEDChar2-CEDChar3-CEDChar4-CEDChar5-CEDChar6-CEDChar7       


Преобразованый к привычному формату, данные из диаграмы выглядят так:
------------Начало страницы-------------------
                (раздел0)
  (абзац0) (пустой)
  (абзац1)
(строка0)(символы0,1,2)
(строка1)(символы3,4,5)
(строка2)(пустая)
(строка3)(пустая)
(строка4)(пустая)
----------------разрыв раздела----------------
                 (раздел1)
(абзац2) (пустой)
(абзац3) (пустой)
----------------разрыв раздела----------------
              (раздел2) (пустой)
----------------разрыв раздела----------------
              (раздел3) (пустой)
----------------разрыв раздела----------------
              (раздел4) 
  (абзац4) 
(строка5)(символы6,7)

По этой диаграмме можно путешествовать как сверху вниз, так и по горизонтали.
Для путешествий по горизонтали в классе CEDPage есть ф-ции 
CEDSection * GetSection(int _num);
CEDParagraph * GetParagraph(int _num);
CEDLine * GetLine(int _num);
CEDChar * GetChar(int _num);
которые возвращают указатель на соответствующий элемент. _num - сквозной номер
элемента(та цифра, которая нарисована на картинке вверху).

В каждом узле хранится т.н. текущий элемент более низкого уровня.
Все операции в структуре происходят относительно него. 
Каждый из вышеперечисленных классов(за исключением CEDChar) имеет ф-ции работы с
текущим эл-том. 
Номер или адрес текущего 
элемента можно получить с помощью функций GetNumOfCur... и GetCur..., где под ... подразумевается элемент 
нижестоящего класса. 
Всё это сделано для
того, чтобы можно было хранить один глобальный указатель на CEDPage, а
для доступа к содержимому дерева из различных функций использовать
конструкции вида 
myPage->GetCurSection()->GetCurParagraph()->userNumber=0;

При создании объекта текущий эл-т устанавливается равным 0, после добавления
объекта более низкого уровня - начинает указывать на него.

Текущий элемент можно изменить 
непосредственным присаиванием, либо заданием его порядкового номера 
с помощью функций SetCur...
В качестве порядкового номера здесь выступает не сквозной номер, а номер
в текущем узле. На картинке:абзац0 можно получить так:
section0->SetCurParagraph(0);
абзац2 так:
section1->SetCurParagraph(0);
абзац3:
section1->SetCurParagraph(1);
и т.п.

Также существуют ф-ции Next...(Bool32 _goThroughSect)  и 
Prev...(Bool32 _goThroughSect), которые 
возвращают соответственно 
следующий или предыдущий элементы относительно текущего. Аргмент указывает,
что возвращать, если следующий элемент более низкого уровня имеет другого
родителя, чем текущий. Если аргумент - FALSE, то возвращается 0, иначе возвращается 
элемент. Напр. (картинка) если в разделе1 текущим является абзац3, то
section1->NextParagraph(FALSE)==0;
section1->NextParagraph(TRUE)==paragraph4.

Существует еще один способ изменить текущий элемент - это ф-ции
Bool32	GoToNextSection();
Bool32	GoToNextParagraph();
Bool32	GoToNextLine();
Bool32	GoToNextChar();
определенные в классе CEDPage.
Рассмотрим, к примеру GoToNextLine. Она берет текущую секцию, там - текущий
абзац, там - текущую строку и делает текущей строку, идущую следом. Если
эта новая строка находится в следующем абзаце, то сменяется и текущий абзац
и т.д. Фактически, конструкция 
myPage->GetCurSection()->GetCurParagraph()->GetCurLine() начинает указывать
на следующую строку. Ф-ции возвращают TRUE, если текущий элемент был
успешно изменен, и FALSE в противном случае. FALSE означает, что текущий
эл-т является последним на данном уровне дерева либо что на одном из
уровней дерева текущий эл-т не имеет детей. Напр, на рисунке, это будет
в случае GoToNextParagraph(), если текущими являются секция4 и абзац4. Или
GoToNextLine(), если текущие секция1 и абзац2 (нет детей)

Добавить элемент в дерево можно при помощи ф-ций Insert... Вставится он
сразу после текущего. Ф-ции Insert... возвращают 
указатель на вновь вставленный эл-т, и делают этот новый эл-т текущим.
 Напр. если в CEDSection три абзаца и текущим
является 2й, то комада mySection->InsertParagraph() вставит новый абзац 
на 3е место, старый абзац номер3 станет четвёртым, текущим станет абзац3,
указатель на который будет возвращен.

Ф-ции из CEDPage
int	GetNumberOfSections();
int	GetNumberOfParagraphs();
int	GetNumberOfLines();
int	GetNumberOfChars();
возвращают количество соответствующих элементов в дереве

 Каждый из CED классов имеет поля extData и extDataLen(длина в байтах).
Туда помещается та информация, которая была или должна быть записана
в ed файле сразу вслед за информацией, взятой из класса. В качестве этой
информации должны выступать исключительно структуры расширенного ed 
(edExtension). Информация по ситаксису таких структур лежит в ed-discr.txt.

			Иерархическая структура

На самом верху мы имеем CEDPage. Этот класс хранит данные о всей странице
в целом. Это:

EDSIZE	sizeOfImage		//Размеры исходной картинки в пикселях
EDSIZE	dpi;			//Разрешение сканера для этой картинки
int	turn;			//Тангенс угла поворота картинки относительно вертикали*2048
char*	imageName;		//Имя файла изображения. Если путь не указан, ищется в одном 
				//каталоге с ed файлом

int	pageNumber;		//Номер страницы(=0 не в пакетном режиме)
EDSIZE	pageSizeInTwips;	//Ширина страницы в твипах(1дюйм=1440твипов) для текстового редактора


Далее следуют классы CEDSection. Каждый из них может сожержать
несколько абзатцев. Информация по форматированию (где начинать колонки,
где - таблицы и картини) хранится в заголовках соответствующих абзатцев.
Класс содержит:
int		numberOfColumns;	//Количество колонок в секции(n штук)
EDRECT	borders;			//отступы от края бумаги

поле borders аналогично полю в rtf. В нем сожержится информация по 
левому и правому отступах от края бумаги, относительно которых будут
выравниваться абзацы(см. серая зона на Линейке Word'a). Верхний и нижний
отступы учитываются лишь в том случае, если абзац первый(соответственно 
последний) на странице.

На следующем уровне мы встречаем CEDParagraph. Этот класс описывает абзацы.

int	type;					//Тип абзаца
int	alligment;				//Выравнивание абзатца
EDRECT	ident;					//Отступы: left=левый, right=ширина,top=красн.строка(в твипах)
int	userNumber;				//Номер, данный пользователем на этапе фрагментации
int	border;					//Рамка вокруг абзатца
EDSIZE	interval;				//cx-верхний отступ, cy- нижний
edBox	layout;					//Расположение абзаца на странице
void * descriptor;			//Указатель на расширенный описатель специальных структур

Самые интересные поля здесь - type  и descriptor. Каждому типу абзаца 
соответстует свой описатель, либо не соответствует никакой(=0). Стили
могут комбинироваться оператором '|'.
Рассмотрим различные варианты форматирования:

колонки - для того, чтобы описать колонки, следует в заголовке секции указать
их число, каждую колонку начинать фиктивным абзатцем с типом
COLUMN_BEGIN и descriptor=EDCOLDISCR,где width=ширине колонки, spacing=расстоянию
до следующей,next - указатель на начало следующей колонки(если колонка
последняя- то 0).В конце последней
колонки присвоить фиктивному абзацу тип LAST_IN_COLUMN,
descriptor=0

Для всего этого можно использовать ф-цию из CEDSection
CEDParagraph * CreateColumn();
которая создает обрамляющие абзацы, увеличивает на 1 счетчик колонок, 
текущим делает первый фиктивный абзац. Возвращается указатель, который
можно передавать ф-ции из CEDSection
CEDParagraph * CreateParagraph(CEDParagraph * hObject,int align, EDRECT indent, int UserNum,int FlagBorder,
			       EDSIZE interval, edBox layout, int  color, int  shading, int spaceBetweenLines, 
			       char spcBtwLnsMult, char  keep);
(см. ниже)

фрейм(рамка) - Все фреймы должны лежать после колонок. Каждый фрейм начинать 
фиктивным абзатцем с типом
FRAME_BEGIN и descriptor=EDFRAMEDISCR, указывающий на структуру, содержащую 
координаты в твипах фрейма относительно страницы и ее размер,где 
 rec-размер,next - указатель на начало следующго фрейма(если фрейм
последний- то 0).В конце последнго
фрейма присвоить фиктивному абзацу тип FRAME_END,
descriptor=0 
Для всего этого можно использовать ф-цию из CEDSection
CEDParagraph * CreateFrame(CEDParagraph* hObject, edBox rect, char position=-1, DWORD borderSpace=-1, 
			   DWORD dxfrtextx=-1, DWORD dxfrtexty=-1)
которая создает обрамляющие абзацы, 
текущим делает первый фиктивный абзац. Возвращается указатель, который
можно передавать ф-ции из CEDSection
CEDParagraph * CreateParagraph(CEDParagraph * hObject,int align, EDRECT indent, int UserNum,int FlagBorder,
			       EDSIZE interval, edBox layout, int  color, int  shading, int spaceBetweenLines, 
			       char spcBtwLnsMult, char  keep);

(см. ниже)


картинка - тип PICTURE,
descriptor = ctp_pic_hdr*. Описание структуры- см. ed-discr.txt

таблица - таблица начинается фиктивным абзацем, который имеет тип TAB_BEGIN,
descriptor= указатель на структуру edTabDescr. Далее идет фиктивный абзац,
описывающий строку таблицы с типом TAB_ROW_BEGIN, descriptor=указатель на структуру edRowDescr
далее идет фиктивный абзац, описывающий ячейку с типом TAB_CELL_BEGIN и соотв. дискриптором,
ячейка, еще один и.т.д., потом снова TAB_ROW_BEGIN и в самом конце - TAB_END, descriptor=0.


Других типов абзацев на данный момент не существует. 

Следующий уровень - строки - CEDLine.
Класс не обладает никакой содержательной информацией, служит лишь
для разбиения сиволов внутри абзацев

И, наконец, CEDChar

edRect		layout;			//Размещение символа на исходном изображении(в пикселях)
int		fontHeight,fontAttribs;	//параметры шрифта
letter * alternatives;	//Массив альтернатив


			Чтение ed-файлов

Для чтения файлов в подобную структуру, библиотека имеет экспортируемую функцию
CEDPage * CED_FormattedLoad (char * file,Bool32 readFromFile, Word32 bufLen);

Если readFromFile=TRUE, то file должен содержать имя файла, bufLen - игнорируется
Если readFromFile=FALSE, то file - указатель на область в памяти, где лежит ed, 
                         BufLen - размер этого буфера

, возвращающую указатель на CEDPage. Полученный указатель 
можно, после необходимых вам преобразований в структуре передать в функию 
CED_FormattedWrite. По окончанию работы со стуктурой, следует вызвать для 
нее 
void CED_DeleteTree(CEDPage * pg). Все нижестоящие 
классы удаляются автоматически.




Hosted by uCoz