Add bezier rendering.
This commit is contained in:
parent
b7f75f903e
commit
1eeaebd0a9
3 changed files with 65 additions and 33 deletions
|
@ -1,21 +1,22 @@
|
||||||
#include "FontGlyph.h"
|
#include "FontGlyph.h"
|
||||||
|
|
||||||
void GlyphRunOutlines::addToFeature(const Point& point)
|
void GlyphRunOutlines::addSegment(const GlyphRunSegment& segment)
|
||||||
{
|
{
|
||||||
mFeatures[mFeatures.size() - 1].mPoints.push_back(point);
|
mFeatures[mFeatures.size() - 1].mSegments.push_back(segment);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlyphRunOutlines::startFeature(const Point& point, bool isFilled)
|
void GlyphRunOutlines::startFeature(const Point& point, bool isFilled)
|
||||||
{
|
{
|
||||||
GlyphRunOutline feature;
|
GlyphRunFeature feature;
|
||||||
feature.mFilled = isFilled;
|
feature.mFilled = isFilled;
|
||||||
feature.mPoints.push_back(point);
|
|
||||||
mFeatures.push_back(feature);
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<GlyphRunOutline> GlyphRunOutlines::getFeatures() const
|
GlyphRunSegment segment;
|
||||||
{
|
segment.mType = GlyphRunSegment::Type::POINT;
|
||||||
return mFeatures;
|
segment.mPoints.push_back(point);
|
||||||
|
|
||||||
|
feature.mSegments.push_back(segment);
|
||||||
|
|
||||||
|
mFeatures.push_back(feature);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GlyphRunOutlines::toPostScriptPath()
|
std::string GlyphRunOutlines::toPostScriptPath()
|
||||||
|
@ -23,15 +24,31 @@ std::string GlyphRunOutlines::toPostScriptPath()
|
||||||
std::string path;
|
std::string path;
|
||||||
for (const auto& feature : mFeatures)
|
for (const auto& feature : mFeatures)
|
||||||
{
|
{
|
||||||
if (feature.mPoints.empty())
|
if (feature.mSegments.empty())
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto last_point = feature.mPoints[0];
|
|
||||||
path += "M" + std::to_string(last_point.getX()) + " " + std::to_string(last_point.getY()) + " ";
|
auto start_point = feature.mSegments[0].mPoints[0];
|
||||||
for (std::size_t idx = 1; idx < feature.mPoints.size(); idx++)
|
path += "M" + std::to_string(start_point.getX()) + " " + std::to_string(start_point.getY()) + " ";
|
||||||
|
|
||||||
|
for (std::size_t idx = 1; idx < feature.mSegments.size(); idx++)
|
||||||
{
|
{
|
||||||
path += "L" + std::to_string(feature.mPoints[idx].getX()) + " " + std::to_string(feature.mPoints[idx].getY()) + " ";
|
if (feature.mSegments[idx].mType == GlyphRunSegment::Type::LINE)
|
||||||
|
{
|
||||||
|
for (const auto& point : feature.mSegments[idx].mPoints)
|
||||||
|
{
|
||||||
|
path += "L" + std::to_string(point.getX()) + " " + std::to_string(point.getY()) + " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (feature.mSegments[idx].mType == GlyphRunSegment::Type::BEZIER)
|
||||||
|
{
|
||||||
|
path += "C";
|
||||||
|
for (const auto& point : feature.mSegments[idx].mPoints)
|
||||||
|
{
|
||||||
|
path += std::to_string(point.getX()) + " " + std::to_string(point.getY()) + " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
path += "z ";
|
path += "z ";
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,23 +7,33 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
struct GlyphRunOutline
|
struct GlyphRunSegment
|
||||||
|
{
|
||||||
|
enum class Type
|
||||||
|
{
|
||||||
|
POINT,
|
||||||
|
LINE,
|
||||||
|
BEZIER
|
||||||
|
};
|
||||||
|
std::vector<Point> mPoints;
|
||||||
|
Type mType{ Type::LINE };
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GlyphRunFeature
|
||||||
{
|
{
|
||||||
bool mFilled{ true };
|
bool mFilled{ true };
|
||||||
std::vector<Point> mPoints;
|
std::vector<GlyphRunSegment> mSegments;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GlyphRunOutlines
|
class GlyphRunOutlines
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void addToFeature(const Point& point);
|
void addSegment(const GlyphRunSegment& point);
|
||||||
void startFeature(const Point& point, bool isFilled);
|
void startFeature(const Point& point, bool isFilled);
|
||||||
|
|
||||||
const std::vector<GlyphRunOutline> getFeatures() const;
|
|
||||||
|
|
||||||
std::string toPostScriptPath();
|
std::string toPostScriptPath();
|
||||||
private:
|
private:
|
||||||
std::vector<GlyphRunOutline> mFeatures;
|
std::vector<GlyphRunFeature> mFeatures;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FontGlyph
|
class FontGlyph
|
||||||
|
|
|
@ -56,59 +56,64 @@ ULONG __stdcall GlyphOutlineGeometrySink::Release()
|
||||||
|
|
||||||
void __stdcall GlyphOutlineGeometrySink::SetFillMode(D2D1_FILL_MODE fillMode)
|
void __stdcall GlyphOutlineGeometrySink::SetFillMode(D2D1_FILL_MODE fillMode)
|
||||||
{
|
{
|
||||||
MLOG_INFO("SetFillMode: " << bool(fillMode == D2D1_FILL_MODE_ALTERNATE));
|
//MLOG_INFO("SetFillMode: " << bool(fillMode == D2D1_FILL_MODE_ALTERNATE));
|
||||||
}
|
}
|
||||||
|
|
||||||
void __stdcall GlyphOutlineGeometrySink::SetSegmentFlags(D2D1_PATH_SEGMENT vertexFlags)
|
void __stdcall GlyphOutlineGeometrySink::SetSegmentFlags(D2D1_PATH_SEGMENT vertexFlags)
|
||||||
{
|
{
|
||||||
MLOG_INFO("SetSegmentFlags");
|
|
||||||
if (vertexFlags == D2D1_PATH_SEGMENT_NONE)
|
if (vertexFlags == D2D1_PATH_SEGMENT_NONE)
|
||||||
{
|
{
|
||||||
MLOG_INFO("D2D1_PATH_SEGMENT_NONE");
|
|
||||||
}
|
}
|
||||||
else if (vertexFlags == D2D1_PATH_SEGMENT_FORCE_UNSTROKED)
|
else if (vertexFlags == D2D1_PATH_SEGMENT_FORCE_UNSTROKED)
|
||||||
{
|
{
|
||||||
MLOG_INFO("D2D1_PATH_SEGMENT_FORCE_UNSTROKED");
|
|
||||||
}
|
}
|
||||||
else if (vertexFlags == D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN)
|
else if (vertexFlags == D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN)
|
||||||
{
|
{
|
||||||
MLOG_INFO("D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN");
|
|
||||||
}
|
}
|
||||||
else if (vertexFlags == D2D1_PATH_SEGMENT_FORCE_DWORD)
|
else if (vertexFlags == D2D1_PATH_SEGMENT_FORCE_DWORD)
|
||||||
{
|
{
|
||||||
MLOG_INFO("D2D1_PATH_SEGMENT_FORCE_DWORD");
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MLOG_INFO("UKNOWN");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void __stdcall GlyphOutlineGeometrySink::BeginFigure(D2D1_POINT_2F startPoint, D2D1_FIGURE_BEGIN figureBegin)
|
void __stdcall GlyphOutlineGeometrySink::BeginFigure(D2D1_POINT_2F startPoint, D2D1_FIGURE_BEGIN figureBegin)
|
||||||
{
|
{
|
||||||
MLOG_INFO("BeginFigure, is filled: " << bool(figureBegin == D2D1_FIGURE_BEGIN_FILLED));
|
|
||||||
mGlyphRunOutline->startFeature(Point(startPoint.x, startPoint.y), figureBegin == D2D1_FIGURE_BEGIN_FILLED);
|
mGlyphRunOutline->startFeature(Point(startPoint.x, startPoint.y), figureBegin == D2D1_FIGURE_BEGIN_FILLED);
|
||||||
}
|
}
|
||||||
|
|
||||||
void __stdcall GlyphOutlineGeometrySink::AddLines(_In_reads_(pointsCount) CONST D2D1_POINT_2F* points, UINT32 pointsCount)
|
void __stdcall GlyphOutlineGeometrySink::AddLines(_In_reads_(pointsCount) CONST D2D1_POINT_2F* points, UINT32 pointsCount)
|
||||||
{
|
{
|
||||||
MLOG_INFO("AddLines");
|
GlyphRunSegment segment;
|
||||||
|
segment.mType = GlyphRunSegment::Type::LINE;
|
||||||
for (UINT32 idx = 0; idx < pointsCount; idx++)
|
for (UINT32 idx = 0; idx < pointsCount; idx++)
|
||||||
{
|
{
|
||||||
auto point = points[idx];
|
auto point = points[idx];
|
||||||
MLOG_INFO("Adding point: " << point.x << " " << point.y);
|
segment.mPoints.push_back(Point(point.x, point.y));
|
||||||
mGlyphRunOutline->addToFeature(Point(point.x, point.y));
|
|
||||||
}
|
}
|
||||||
|
mGlyphRunOutline->addSegment(segment);
|
||||||
}
|
}
|
||||||
|
|
||||||
void __stdcall GlyphOutlineGeometrySink::AddBeziers(_In_reads_(beziersCount) CONST D2D1_BEZIER_SEGMENT* beziers, UINT32 beziersCount)
|
void __stdcall GlyphOutlineGeometrySink::AddBeziers(_In_reads_(beziersCount) CONST D2D1_BEZIER_SEGMENT* beziers, UINT32 beziersCount)
|
||||||
{
|
{
|
||||||
MLOG_INFO("AddBeziers");
|
for (UINT32 idx = 0; idx < beziersCount; idx++)
|
||||||
|
{
|
||||||
|
GlyphRunSegment segment;
|
||||||
|
segment.mType = GlyphRunSegment::Type::BEZIER;
|
||||||
|
|
||||||
|
auto bezier = beziers[idx];
|
||||||
|
segment.mPoints.push_back(Point(bezier.point1.x, bezier.point1.y));
|
||||||
|
segment.mPoints.push_back(Point(bezier.point2.x, bezier.point2.y));
|
||||||
|
segment.mPoints.push_back(Point(bezier.point3.x, bezier.point3.y));
|
||||||
|
|
||||||
|
mGlyphRunOutline->addSegment(segment);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void __stdcall GlyphOutlineGeometrySink::EndFigure(D2D1_FIGURE_END figureEnd)
|
void __stdcall GlyphOutlineGeometrySink::EndFigure(D2D1_FIGURE_END figureEnd)
|
||||||
{
|
{
|
||||||
MLOG_INFO("EndFigure");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT __stdcall GlyphOutlineGeometrySink::Close()
|
HRESULT __stdcall GlyphOutlineGeometrySink::Close()
|
||||||
|
|
Loading…
Reference in a new issue