GenQuadChild(0, QTC_TOP_LEFT);
}
+int Document::ClipObjectToQuadChild(int object_id, QuadTreeNodeChildren type)
+{
+ switch (m_objects.types[object_id])
+ {
+ case RECT_FILLED:
+ case RECT_OUTLINE:
+ {
+ Rect obj_bounds = TransformToQuadChild(m_objects.bounds[object_id], type);
+ if (obj_bounds.x < 0)
+ {
+ obj_bounds.w += obj_bounds.x;
+ obj_bounds.x = 0;
+ }
+ if (obj_bounds.y < 0)
+ {
+ obj_bounds.h += obj_bounds.y;
+ obj_bounds.y = 0;
+ }
+ if (obj_bounds.x + obj_bounds.w > 1)
+ {
+ obj_bounds.w += (1 - (obj_bounds.x + obj_bounds.w));
+ }
+ if (obj_bounds.y + obj_bounds.h > 1)
+ {
+ obj_bounds.h += (1 - (obj_bounds.y + obj_bounds.h));
+ }
+ m_objects.bounds.push_back(obj_bounds);
+ m_objects.types.push_back(m_objects.types[object_id]);
+ m_objects.data_indices.push_back(m_objects.data_indices[object_id]);
+ return 1;
+ }
+ default:
+ Debug("Adding %s -> %s", m_objects.bounds[object_id].Str().c_str(), TransformToQuadChild(m_objects.bounds[object_id], type).Str().c_str());
+ m_objects.bounds.push_back(TransformToQuadChild(m_objects.bounds[object_id], type));
+ m_objects.types.push_back(m_objects.types[object_id]);
+ m_objects.data_indices.push_back(m_objects.data_indices[object_id]);
+ return 1;
+ }
+ return 0;
+}
QuadTreeIndex Document::GenQuadChild(QuadTreeIndex parent, QuadTreeNodeChildren type)
{
QuadTreeIndex new_index = m_quadtree.nodes.size();
m_quadtree.nodes[new_index].object_begin = m_objects.bounds.size();
for (unsigned i = m_quadtree.nodes[parent].object_begin; i < m_quadtree.nodes[parent].object_end; ++i)
{
- if (ContainedInQuadChild(m_objects.bounds[i], type))
+ if (IntersectsQuadChild(m_objects.bounds[i], type))
{
- m_objects.bounds.push_back(TransformToQuadChild(m_objects.bounds[i], type));
- m_objects.types.push_back(m_objects.types[i]);
- m_objects.data_indices.push_back(m_objects.data_indices[i]);
- m_count++;
+ m_count += ClipObjectToQuadChild(i, type);
}
}
m_quadtree.nodes[new_index].object_end = m_objects.bounds.size();
bool start = false;
- static string delims("()[],{}<>;:=LlmMqQzZcC");
+ static string delims("()[],{}<>;:=LlHhVvmMqQzZcC");
- while (i < d.size() && GetToken(d, token, i).size() > 0)
+ while (i < d.size() && GetToken(d, token, i, delims).size() > 0)
{
if (isalpha(token[0]))
command = token;
}
- else if (command == "l" || command == "L")
+ else if (command == "l" || command == "L" || command == "h" || command == "H" || command == "v" || command == "V")
{
Debug("Construct lineto command, relative %d", relative);
Real dx = Real(strtod(GetToken(d,token,i,delims).c_str(),NULL));
- assert(GetToken(d,token,i,delims) == ",");
- Real dy = Real(strtod(GetToken(d,token,i,delims).c_str(),NULL));
+ Real dy;
+ if (command == "l" || command == "L")
+ {
+ assert(GetToken(d,token,i,delims) == ",");
+ dy = Real(strtod(GetToken(d,token,i,delims).c_str(),NULL));
+ }
+ else if (command == "v" || command == "V")
+ {
+ swap(dx,dy);
+ }
x[1] = (relative) ? x[0] + dx : dx;
y[1] = (relative) ? y[0] + dy : dy;
+ if (command == "v" || command == "V")
+ {
+ x[1] = x[0];
+ }
+ else if (command == "h" || command == "H")
+ {
+ y[1] = y[0];
+ }
Real x1(x[1]);
Real y1(y[1]);
float font_scale = stbtt_ScaleForPixelHeight(&m_font, scale);
Real x0(x);
//Real y0(y);
+ int ascent = 0, descent = 0, line_gap = 0;
+ stbtt_GetFontVMetrics(&m_font, &ascent, &descent, &line_gap);
+ Real y_advance = Real(font_scale) * Real(ascent - descent + line_gap);
for (unsigned i = 0; i < text.size(); ++i)
{
if (text[i] == '\n')
{
- y += 0.5*scale;
+ y += y_advance;
x = x0;
}
if (!isprint(text[i]))
continue;
+ int advance_width = 0, left_side_bearing = 0, kerning = 0;
+ stbtt_GetCodepointHMetrics(&m_font, text[i], &advance_width, &left_side_bearing);
+ if (i > 1)
+ {
+ kerning = stbtt_GetCodepointKernAdvance(&m_font, text[i-1], text[i]);
+ }
+ x += Real(font_scale) * Real(left_side_bearing + kerning);
AddFontGlyphAtPoint(&m_font, text[i], font_scale, x, y);
- x += 0.5*scale;
+ x += Real(font_scale) * Real(advance_width);
}
}