filters

fstring.cpp
1/*
2 * Copyright (c) 2002-2003 Nicolas HADACEK (hadacek@kde.org)
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20#include "fstring.h"
21
22#include <tdeglobal.h>
23#include <kdebug.h>
24
25#include "data.h"
26#include "transform.h"
27
28
29namespace PDFImport {
30
31//-----------------------------------------------------------------------------
32TQDomElement Tabulator::createElement(Data &data) const
33{
34 TQDomElement element = data.createElement("TABULATOR");
35 element.setAttribute("type", alignment);
36 element.setAttribute("ptpos", pos);
37 element.setAttribute("filling", filling);
38 if ( alignment==Character )
39 element.setAttribute("alignchar", TQString(alignmentChar));
40 return element;
41}
42
43//-----------------------------------------------------------------------------
44Paragraph::Paragraph()
45 : type(Body), firstIndent(0), leftIndent(0), align(AlignLeft)
46{}
47
48Paragraph::Paragraph(TextLine *first, uint nbLines)
49 : type(Body), firstIndent(0), leftIndent(0), align(AlignLeft)
50{
51 // fill line list
52 TextLine *line = first;
53 for (uint i=0; i<nbLines; i++) {
54 Q_ASSERT( line!=0 );
55 _lines.append(line);
56 line = line->next;
57 }
58
59 // compute rectangle
60 TQValueList<TextLine *>::const_iterator it;
61 for (it = _lines.begin(); it!=_lines.end(); ++it)
62 for (TextBlock *block = (*it)->blocks; block; block = block->next) {
63 DRect br(block->xMin, block->xMax, block->yMin, block->yMax);
64 _rect.unite(br);
65 }
66}
67
68int Paragraph::findTab(double xMin, const TextLine *line) const
69{
70 double epsilon = 0.1 * (line->yMax - line->yMin);
71 double dx = xMin - (isFirst(line) ? firstIndent : leftIndent);
72 if ( fabs(dx)<epsilon ) return -2;
73 for (uint i=0; i<tabs.size(); i++)
74 if ( fabs(xMin-tabs[i].pos)<epsilon ) return i;
75 return -1;
76}
77
78uint Paragraph::findNbTabs(uint i, double prevXMax) const
79{
80 uint k = 0;
81 for (; k<tabs.size(); k++)
82 if ( tabs[k].pos>prevXMax ) break;
83 if ( k>i ) return 0;
84 return i-k+1;
85}
86
87int Paragraph::charFromEnd(uint dec, uint &bi) const
88{
89 uint k = 0;
90 for (uint i=blocks.size(); i>0; i--) {
91 for (uint j=blocks[i-1].text.length(); j>0; j--) {
92 if ( k==dec ) {
93 bi = i-1;
94 return j-1;
95 }
96 k++;
97 }
98 }
99 return -1;
100}
101
102//-----------------------------------------------------------------------------
103String::String(GfxState *state, double x0, double y0,
104 double fontSize, uint frameIndex)
105 : TextString(state, x0, y0, fontSize), link(0), _frameIndex(frameIndex)
106{
107 _font = Font(state, fontSize);
108}
109
110void String::addChar(GfxState *state, double x, double y,
111 double dx, double dy, Unicode u)
112{
113 Unicode res[MaxLigatureLength];
114 uint nb = checkLigature(u, res);
115 TQString sdebug;
116 if ( nb>1 ) sdebug = "found ligature ";
117 double ddx = dx / nb;
118 for (uint i=0; i<nb; i++) {
119 TextString::addChar(state, x + ddx*i, y, ddx, dy, res[i]);
120 if ( nb>1 ) sdebug += TQChar(res[i]);
121 }
122 if ( nb>1 ) kdDebug(30516) << sdebug << endl;
123 else checkCombination(this);
124}
125
126bool String::checkCombination(TextString *str)
127{
128 if ( len<1 || str->len<1 ) return false;
129 if ( str==this && len<2 ) return false;
130
131 struct CharData {
132 int i;
133 DRect r;
134 Unicode u;
135 };
136 CharData letter, accent;
137 letter.i = (str==this ? len-1 : 0);
138 letter.u = str->text[letter.i];
139 accent.i = (str==this ? len-2 : len-1);
140 accent.u = text[accent.i];
141 Unicode res = checkCombi(letter.u, accent.u);
142 if ( res==0 ) return false;
143
144 letter.r.setLeft(letter.i==0 ? str->xMin : str->xRight[letter.i-1]);
145 letter.r.setRight(str->xRight[letter.i]);
146 letter.r.setTop(str->yMin);
147 letter.r.setBottom(str->yMax);
148 accent.r.setLeft(accent.i==0 ? xMin : xRight[accent.i-1]);
149 accent.r.setRight(xRight[accent.i]);
150 accent.r.setTop(yMin);
151 accent.r.setBottom(yMax);
152 bool ok = ( more(accent.r.left(), letter.r.left(), 0.005)
153 && less(accent.r.right(), letter.r.right(), 0.005) );
154 // #### above/below detection is not right !!!
155// bool above = more(accent.r.bottom, letter.r.top);
156// bool below = more(accent.r.top, letter.r.bottom);
157// kdDebug(30516) << "found combi " << TQString(TQChar(res))
158// << " accent: " << accent.r.toString() << endl;
159// kdDebug(30516) << "letter: " << letter.r.toString()
160// << endl;
161 // #### FIXME we should check for above or below accent !!!
162 if ( !ok ) return false;
163// if (below) {
164 // #### TODO
165// kdDebug(30516) << "accent below !" << endl;
166// return false;
167// } else if ( !above ) {
168// kdDebug(30516) << "accent inside letter ??" << endl;
169// return false;
170// }
171// kdDebug(30516) << "combi ok" << endl;
172
173 // replace accent by accented letter
174 text[accent.i] = res;
175 xMax = letter.r.right();
176 if ( accent.i==0 ) xMin = letter.r.left();
177 else xRight[accent.i-1] = letter.r.left();
178 yMin = kMin(yMin, str->yMin);
179 yMax = kMax(yMax, str->yMax);
180
181 // append remaining string
182 if ( str==this ) {
183 len--;
184 for (int k=letter.i+1; k<str->len; k++) {
185 xRight[k-1] = xRight[k];
186 text[k-1] = text[k];
187 }
188 } else {
189 for (int k=letter.i+1; k<str->len; k++)
190 TextString::addChar(0, str->xRight[k-1], 0,
191 str->xRight[k] - str->xRight[k-1], 0,
192 str->text[k]);
193 str->len = 0;
194 }
195
196 return true;
197}
198
199} // namespace
The body is a frameset.
Definition body.h:38