-
Notifications
You must be signed in to change notification settings - Fork 0
/
boxbuilder.cpp
129 lines (100 loc) · 4.63 KB
/
boxbuilder.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include "boxbuilder.h"
#include <iostream>
#include <QTextBlock>
#include <QTextLayout>
#include <QPainter>
void BoxBuilder::handleGlyphRun_(const QGlyphRun& glyphRun)
{
QPainter painter_(&pixmap_);
painter_.setPen(glyphPen_);
painter_.drawGlyphRun(glyphPosition_,glyphRun);
QVector<quint32> indices = glyphRun.glyphIndexes();
QVector<QPointF> positions = glyphRun.positions();
if(indices.size() != positions.size())
log_ << "the number of indices and the number of positions are different: "
<< indices.size() << " and " << positions.size() << std::endl;
QVector<QPointF>::Iterator posit = positions.begin();
qreal posx = glyphPosition_.x(),
posy = glyphPosition_.y();
for(QVector<quint32>::iterator ixIt = indices.begin();ixIt != indices.end();++ixIt)
{
QRawFont rawFont = glyphRun.rawFont();
QPainterPath painterPath = rawFont.pathForGlyph(*ixIt);
QRectF glyphBoundingRect = painterPath.boundingRect();
QVector<uint> blockTextIndices(blockText_.length());
int blockTextIndicesSize = blockTextIndices.size();
rawFont.glyphIndexesForChars(blockText_.begin(),blockText_.length(),blockTextIndices.begin(),&blockTextIndicesSize);
std::map<uint,QChar> glyphIndicesToChars;
std::wstring blockTextStdw = blockText_.toStdWString();
// build index for acessing chars in text, since glyphs order may not correspond chars order in text
for(int i = 0; i < blockTextIndices.size(); ++i)
glyphIndicesToChars[blockTextIndices[i] ] = blockText_.at(i);
QChar currentChar = glyphIndicesToChars[*ixIt];
unsigned histValue = 0;
if(histogram.find(currentChar) == histogram.end())
histogram[currentChar] = 0;
else histValue = ++histogram[currentChar];
maxHistogramValue = std::max(maxHistogramValue,histValue);
//std::wcout << "processing \" "<< QString(currentChar).toStdWString() << " \"... " << std::endl;
//
//
//log_ << "glyphBoundingRect = (" << glyphBoundingRect.x() << "," << glyphBoundingRect.y() <<
// "," << glyphBoundingRect.width() << "," << glyphBoundingRect.height() << ")" << std::endl;
QRect screenBoundingRect(
posx + posit->x() + glyphBoundingRect.x(),
posy + posit->y() + glyphBoundingRect.y(),
glyphBoundingRect.width()+1,
glyphBoundingRect.height()+1);
/* log_ << "screen layout position = (" << posx << "," << posy << ")" << std::endl;
log_ << "screen glyph position = (" << posit->x() << "," << posit->y() << ")" << std::endl;
log_ << "screenBoundingRect = (" << screenBoundingRect.x() << "," << screenBoundingRect.y() <<
"," << screenBoundingRect.width() << "," << screenBoundingRect.height() << ")" << std::end*/;
QRect imageBoundingRect(QPoint( screenBoundingRect.x(),
pixmap_.height()-1 - screenBoundingRect.y() - screenBoundingRect.height()+1),
QPoint( screenBoundingRect.x() + screenBoundingRect.width()-1,
pixmap_.height() - screenBoundingRect.y()-1)
);
//log_ << "imageBoundingRect = (" << imageBoundingRect.x() << "," << imageBoundingRect.y() <<
// "," << imageBoundingRect.width() << "," << imageBoundingRect.height() << ")" << std::endl;
if(glyphBoundingRect.width()&&glyphBoundingRect.height())
boxes_.push_back(box(glyphIndicesToChars[*ixIt],imageBoundingRect));
//painter_.setPen(boxPen_);
painter_.setPen(Qt::green);
//painter_.drawRect(screenBoundingRect);
++posit;
}
}
void BoxBuilder::clearBoxes()
{
boxes_.clear();
histogram.clear();
maxHistogramValue = 0;
}
void BoxBuilder::build(const QTextDocument* doc,const QSize& pixmapSize, const QColor& glyphColor)
{
pixmap_ = QPixmap(pixmapSize);
pixmap_.fill(Qt::white);
glyphPen_ = QPen(glyphColor);
boxes_.clear();
for(QTextBlock block = doc->begin();block!=doc->end();block=block.next())
{
//log_ << "BLOCK has started" << std::endl;
QTextLayout* tl = block.layout();
QString blockText = block.text();
QList<QGlyphRun> glyphs = tl->glyphRuns();
int glyphsNum = 0;
std::for_each(glyphs.begin(),glyphs.end(),[&glyphsNum](QGlyphRun grun)
{
glyphsNum += grun.glyphIndexes().size();
});
if(glyphsNum != blockText.length())
log_ << " the number of glyphs in the layout differs with text length, the numbers are: " <<
glyphsNum << " and " << blockText.length() << std::endl;
glyphPosition_ = tl->position();
blockText_ = blockText;
std::for_each( glyphs.begin(),
glyphs.end(),
[this](const QGlyphRun& grun)
{handleGlyphRun_(grun);});
}
}