void RenderCharPath(const char* gbuf, unsigned total_size, Painter& sw, double xx, double yy) { const char* cur_glyph = gbuf; const char* end_glyph = gbuf + total_size; while(cur_glyph < end_glyph) { const TTPOLYGONHEADER* th = (TTPOLYGONHEADER*)cur_glyph; const char* end_poly = cur_glyph + th->cb; const char* cur_poly = cur_glyph + sizeof(TTPOLYGONHEADER); sw.Move(xx + fx_to_dbl(th->pfxStart.x), yy - fx_to_dbl(th->pfxStart.y)); while(cur_poly < end_poly) { const TTPOLYCURVE* pc = (const TTPOLYCURVE*)cur_poly; if (pc->wType == TT_PRIM_LINE) for(int i = 0; i < pc->cpfx; i++) sw.Line(xx + fx_to_dbl(pc->apfx[i].x), yy - fx_to_dbl(pc->apfx[i].y)); if (pc->wType == TT_PRIM_QSPLINE) { int u; for (u = 0; u < pc->cpfx - 1; u++) { // Walk through points in spline POINTFX pnt_b = pc->apfx[u]; // B is always the current point POINTFX pnt_c = pc->apfx[u+1]; if (u < pc->cpfx - 2) { // If not on last spline, compute C *(int*)&pnt_c.x = (*(int*)&pnt_b.x + *(int*)&pnt_c.x) / 2; *(int*)&pnt_c.y = (*(int*)&pnt_b.y + *(int*)&pnt_c.y) / 2; } sw.Quadratic(xx + fx_to_dbl(pnt_b.x), yy - fx_to_dbl(pnt_b.y), xx + fx_to_dbl(pnt_c.x), yy - fx_to_dbl(pnt_c.y)); } } cur_poly += sizeof(WORD) * 2 + sizeof(POINTFX) * pc->cpfx; } sw.Close(); cur_glyph += th->cb; } }
void Big(Painter& sw) { int n = 0; double sgn = 1; for(int r = 400; r > 5; r -= 3) { for(int i = 0; i < 400; i++) { Pointf p = Polar(sgn * i * M_2PI / 400) * r + Pointf(400, 400); if(i) sw.Line(p); else sw.Move(p); sw.Line(Polar(sgn * (i * M_2PI / 400 + M_2PI / 800)) * (r - 6) + Pointf(400, 400)); n += 2; } sw.Close(); sgn = -sgn; } sw.Fill(Black()); sw.Text(0, 0, "Elements: " + AsString(n), Arial(20)).Fill(Blue()); }
virtual void Close() { sw->Close(); }
bool RenderOutline(const FT_Outline& outline, Painter& path, double xx, double yy) { FT_Vector v_last; FT_Vector v_control; FT_Vector v_start; FT_Vector* point; FT_Vector* limit; char* tags; int n; // index of contour in outline char tag; // current point's state int first = 0; // index of first point in contour for(n = 0; n < outline.n_contours; n++) { int last = outline.contours[n]; limit = outline.points + last; v_start = outline.points[first]; v_last = outline.points[last]; v_control = v_start; point = outline.points + first; tags = outline.tags + first; tag = FT_CURVE_TAG(tags[0]); if(tag == FT_CURVE_TAG_CUBIC) return false; if(tag == FT_CURVE_TAG_CONIC) { if(FT_CURVE_TAG(outline.tags[last]) == FT_CURVE_TAG_ON) { // start at last point if it is on the curve v_start = v_last; limit--; } else { // if both first and last points are conic, // start at their middle and record its position // for closure v_start.x = (v_start.x + v_last.x) / 2; v_start.y = (v_start.y + v_last.y) / 2; v_last = v_start; } point--; tags--; } path.Move(ft_dbl(v_start.x) + xx, -ft_dbl(v_start.y) + yy); while(point < limit) { point++; tags++; tag = FT_CURVE_TAG(tags[0]); switch(tag) { case FT_CURVE_TAG_ON: path.Line(ft_dbl(point->x) + xx, -ft_dbl(point->y) + yy); continue; case FT_CURVE_TAG_CONIC: v_control.x = point->x; v_control.y = point->y; Do_Conic: if(point < limit) { FT_Vector vec; FT_Vector v_middle; point++; tags++; tag = FT_CURVE_TAG(tags[0]); vec.x = point->x; vec.y = point->y; if(tag == FT_CURVE_TAG_ON) { path.Quadratic(ft_dbl(v_control.x) + xx, -ft_dbl(v_control.y) + yy, ft_dbl(vec.x) + xx, -ft_dbl(vec.y) + yy); continue; } if(tag != FT_CURVE_TAG_CONIC) return false; v_middle.x = (v_control.x + vec.x) / 2; v_middle.y = (v_control.y + vec.y) / 2; path.Quadratic(ft_dbl(v_control.x) + xx, -ft_dbl(v_control.y) + yy, ft_dbl(v_middle.x) + xx, -ft_dbl(v_middle.y) + yy); v_control = vec; goto Do_Conic; } path.Quadratic(ft_dbl(v_control.x) + xx, -ft_dbl(v_control.y) + yy, ft_dbl(v_start.x) + xx, -ft_dbl(v_start.y) + yy); goto Close; default: FT_Vector vec1, vec2; if(point + 1 > limit || FT_CURVE_TAG(tags[1]) != FT_CURVE_TAG_CUBIC) return false; vec1.x = point[0].x; vec1.y = point[0].y; vec2.x = point[1].x; vec2.y = point[1].y; point += 2; tags += 2; if(point <= limit) { FT_Vector vec; vec.x = point->x; vec.y = point->y; path.Cubic(ft_dbl(vec1.x) + xx, -ft_dbl(vec1.y) + yy, ft_dbl(vec2.x) + xx, -ft_dbl(vec2.y) + yy, ft_dbl(vec.x) + xx, -ft_dbl(vec.y) + yy); continue; } path.Cubic(ft_dbl(vec1.x) + xx, -ft_dbl(vec1.y) + yy, ft_dbl(vec2.x) + xx, -ft_dbl(vec2.y) + yy, ft_dbl(v_start.x) + xx, -ft_dbl(v_start.y) + yy); goto Close; } } Close: path.Close(); first = last + 1; } return true; }