00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "fstring.h"
00021
00022 #include <kglobal.h>
00023 #include <kdebug.h>
00024
00025 #include "data.h"
00026 #include "transform.h"
00027
00028
00029 namespace PDFImport {
00030
00031
00032 QDomElement Tabulator::createElement(Data &data) const
00033 {
00034 QDomElement element = data.createElement("TABULATOR");
00035 element.setAttribute("type", alignment);
00036 element.setAttribute("ptpos", pos);
00037 element.setAttribute("filling", filling);
00038 if ( alignment==Character )
00039 element.setAttribute("alignchar", QString(alignmentChar));
00040 return element;
00041 }
00042
00043
00044 Paragraph::Paragraph()
00045 : type(Body), firstIndent(0), leftIndent(0), align(AlignLeft)
00046 {}
00047
00048 Paragraph::Paragraph(TextLine *first, uint nbLines)
00049 : type(Body), firstIndent(0), leftIndent(0), align(AlignLeft)
00050 {
00051
00052 TextLine *line = first;
00053 for (uint i=0; i<nbLines; i++) {
00054 Q_ASSERT( line!=0 );
00055 _lines.append(line);
00056 line = line->next;
00057 }
00058
00059
00060 QValueList<TextLine *>::const_iterator it;
00061 for (it = _lines.begin(); it!=_lines.end(); ++it)
00062 for (TextBlock *block = (*it)->blocks; block; block = block->next) {
00063 DRect br(block->xMin, block->xMax, block->yMin, block->yMax);
00064 _rect.unite(br);
00065 }
00066 }
00067
00068 int Paragraph::findTab(double xMin, const TextLine *line) const
00069 {
00070 double epsilon = 0.1 * (line->yMax - line->yMin);
00071 double dx = xMin - (isFirst(line) ? firstIndent : leftIndent);
00072 if ( fabs(dx)<epsilon ) return -2;
00073 for (uint i=0; i<tabs.size(); i++)
00074 if ( fabs(xMin-tabs[i].pos)<epsilon ) return i;
00075 return -1;
00076 }
00077
00078 uint Paragraph::findNbTabs(uint i, double prevXMax) const
00079 {
00080 uint k = 0;
00081 for (; k<tabs.size(); k++)
00082 if ( tabs[k].pos>prevXMax ) break;
00083 if ( k>i ) return 0;
00084 return i-k+1;
00085 }
00086
00087 int Paragraph::charFromEnd(uint dec, uint &bi) const
00088 {
00089 uint k = 0;
00090 for (uint i=blocks.size(); i>0; i--) {
00091 for (uint j=blocks[i-1].text.length(); j>0; j--) {
00092 if ( k==dec ) {
00093 bi = i-1;
00094 return j-1;
00095 }
00096 k++;
00097 }
00098 }
00099 return -1;
00100 }
00101
00102
00103 String::String(GfxState *state, double x0, double y0,
00104 double fontSize, uint frameIndex)
00105 : TextString(state, x0, y0, fontSize), link(0), _frameIndex(frameIndex)
00106 {
00107 _font = Font(state, fontSize);
00108 }
00109
00110 void String::addChar(GfxState *state, double x, double y,
00111 double dx, double dy, Unicode u)
00112 {
00113 Unicode res[MaxLigatureLength];
00114 uint nb = checkLigature(u, res);
00115 QString sdebug;
00116 if ( nb>1 ) sdebug = "found ligature ";
00117 double ddx = dx / nb;
00118 for (uint i=0; i<nb; i++) {
00119 TextString::addChar(state, x + ddx*i, y, ddx, dy, res[i]);
00120 if ( nb>1 ) sdebug += QChar(res[i]);
00121 }
00122 if ( nb>1 ) kdDebug(30516) << sdebug << endl;
00123 else checkCombination(this);
00124 }
00125
00126 bool String::checkCombination(TextString *str)
00127 {
00128 if ( len<1 || str->len<1 ) return false;
00129 if ( str==this && len<2 ) return false;
00130
00131 struct CharData {
00132 int i;
00133 DRect r;
00134 Unicode u;
00135 };
00136 CharData letter, accent;
00137 letter.i = (str==this ? len-1 : 0);
00138 letter.u = str->text[letter.i];
00139 accent.i = (str==this ? len-2 : len-1);
00140 accent.u = text[accent.i];
00141 Unicode res = checkCombi(letter.u, accent.u);
00142 if ( res==0 ) return false;
00143
00144 letter.r.setLeft(letter.i==0 ? str->xMin : str->xRight[letter.i-1]);
00145 letter.r.setRight(str->xRight[letter.i]);
00146 letter.r.setTop(str->yMin);
00147 letter.r.setBottom(str->yMax);
00148 accent.r.setLeft(accent.i==0 ? xMin : xRight[accent.i-1]);
00149 accent.r.setRight(xRight[accent.i]);
00150 accent.r.setTop(yMin);
00151 accent.r.setBottom(yMax);
00152 bool ok = ( more(accent.r.left(), letter.r.left(), 0.005)
00153 && less(accent.r.right(), letter.r.right(), 0.005) );
00154
00155
00156
00157
00158
00159
00160
00161
00162 if ( !ok ) return false;
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174 text[accent.i] = res;
00175 xMax = letter.r.right();
00176 if ( accent.i==0 ) xMin = letter.r.left();
00177 else xRight[accent.i-1] = letter.r.left();
00178 yMin = kMin(yMin, str->yMin);
00179 yMax = kMax(yMax, str->yMax);
00180
00181
00182 if ( str==this ) {
00183 len--;
00184 for (int k=letter.i+1; k<str->len; k++) {
00185 xRight[k-1] = xRight[k];
00186 text[k-1] = text[k];
00187 }
00188 } else {
00189 for (int k=letter.i+1; k<str->len; k++)
00190 TextString::addChar(0, str->xRight[k-1], 0,
00191 str->xRight[k] - str->xRight[k-1], 0,
00192 str->text[k]);
00193 str->len = 0;
00194 }
00195
00196 return true;
00197 }
00198
00199 }