mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-01-16 09:00:26 +01:00
Merge branch 'bug-611-glyph-path' into 'master'
DWrite: More accurate glyph paths for small fonts Closes #611 See merge request cairo/cairo!451
This commit is contained in:
commit
f706ad5aa3
1 changed files with 37 additions and 29 deletions
|
|
@ -736,8 +736,9 @@ _cairo_dwrite_scaled_font_init_glyph_metrics(cairo_dwrite_scaled_font_t *scaled_
|
|||
class GeometryRecorder : public IDWriteGeometrySink
|
||||
{
|
||||
public:
|
||||
GeometryRecorder(cairo_path_fixed_t *aCairoPath)
|
||||
: mCairoPath(aCairoPath) {}
|
||||
GeometryRecorder(cairo_path_fixed_t *aCairoPath, const cairo_matrix_t &matrix)
|
||||
: mCairoPath(aCairoPath)
|
||||
, mMatrix(matrix) {}
|
||||
|
||||
// IUnknown interface
|
||||
IFACEMETHOD(QueryInterface)(IID const& iid, OUT void** ppObject)
|
||||
|
|
@ -779,10 +780,14 @@ public:
|
|||
D2D1_POINT_2F startPoint,
|
||||
D2D1_FIGURE_BEGIN figureBegin)
|
||||
{
|
||||
mStartPoint = startPoint;
|
||||
double x = startPoint.x;
|
||||
double y = startPoint.y;
|
||||
cairo_matrix_transform_point(&mMatrix, &x, &y);
|
||||
mStartPointX = _cairo_fixed_from_double(x);
|
||||
mStartPointY = _cairo_fixed_from_double(y);
|
||||
cairo_status_t status = _cairo_path_fixed_move_to(mCairoPath,
|
||||
_cairo_fixed_from_double(startPoint.x),
|
||||
_cairo_fixed_from_double(startPoint.y));
|
||||
mStartPointX,
|
||||
mStartPointY);
|
||||
(void)status; /* squelch warning */
|
||||
}
|
||||
|
||||
|
|
@ -791,8 +796,8 @@ public:
|
|||
{
|
||||
if (figureEnd == D2D1_FIGURE_END_CLOSED) {
|
||||
cairo_status_t status = _cairo_path_fixed_line_to(mCairoPath,
|
||||
_cairo_fixed_from_double(mStartPoint.x),
|
||||
_cairo_fixed_from_double(mStartPoint.y));
|
||||
mStartPointX,
|
||||
mStartPointY);
|
||||
(void)status; /* squelch warning */
|
||||
}
|
||||
}
|
||||
|
|
@ -802,13 +807,22 @@ public:
|
|||
UINT beziersCount)
|
||||
{
|
||||
for (unsigned int i = 0; i < beziersCount; i++) {
|
||||
double x1 = beziers[i].point1.x;
|
||||
double y1 = beziers[i].point1.y;
|
||||
double x2 = beziers[i].point2.x;
|
||||
double y2 = beziers[i].point2.y;
|
||||
double x3 = beziers[i].point3.x;
|
||||
double y3 = beziers[i].point3.y;
|
||||
cairo_matrix_transform_point(&mMatrix, &x1, &y1);
|
||||
cairo_matrix_transform_point(&mMatrix, &x2, &y2);
|
||||
cairo_matrix_transform_point(&mMatrix, &x3, &y3);
|
||||
cairo_status_t status = _cairo_path_fixed_curve_to(mCairoPath,
|
||||
_cairo_fixed_from_double(beziers[i].point1.x),
|
||||
_cairo_fixed_from_double(beziers[i].point1.y),
|
||||
_cairo_fixed_from_double(beziers[i].point2.x),
|
||||
_cairo_fixed_from_double(beziers[i].point2.y),
|
||||
_cairo_fixed_from_double(beziers[i].point3.x),
|
||||
_cairo_fixed_from_double(beziers[i].point3.y));
|
||||
_cairo_fixed_from_double(x1),
|
||||
_cairo_fixed_from_double(y1),
|
||||
_cairo_fixed_from_double(x2),
|
||||
_cairo_fixed_from_double(y2),
|
||||
_cairo_fixed_from_double(x3),
|
||||
_cairo_fixed_from_double(y3));
|
||||
(void)status; /* squelch warning */
|
||||
}
|
||||
}
|
||||
|
|
@ -818,16 +832,21 @@ public:
|
|||
UINT pointsCount)
|
||||
{
|
||||
for (unsigned int i = 0; i < pointsCount; i++) {
|
||||
double x = points[i].x;
|
||||
double y = points[i].y;
|
||||
cairo_matrix_transform_point(&mMatrix, &x, &y);
|
||||
cairo_status_t status = _cairo_path_fixed_line_to(mCairoPath,
|
||||
_cairo_fixed_from_double(points[i].x),
|
||||
_cairo_fixed_from_double(points[i].y));
|
||||
_cairo_fixed_from_double(x),
|
||||
_cairo_fixed_from_double(y));
|
||||
(void)status; /* squelch warning */
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
cairo_path_fixed_t *mCairoPath;
|
||||
D2D1_POINT_2F mStartPoint;
|
||||
const cairo_matrix_t &mMatrix;
|
||||
cairo_fixed_t mStartPointX;
|
||||
cairo_fixed_t mStartPointY;
|
||||
};
|
||||
|
||||
static cairo_int_status_t
|
||||
|
|
@ -837,7 +856,7 @@ _cairo_dwrite_scaled_font_init_glyph_path(cairo_dwrite_scaled_font_t *scaled_fon
|
|||
cairo_int_status_t status;
|
||||
cairo_path_fixed_t *path;
|
||||
path = _cairo_path_fixed_create();
|
||||
GeometryRecorder recorder(path);
|
||||
GeometryRecorder recorder(path, scaled_font->base.scale);
|
||||
|
||||
DWRITE_GLYPH_OFFSET offset;
|
||||
offset.advanceOffset = 0;
|
||||
|
|
@ -846,12 +865,7 @@ _cairo_dwrite_scaled_font_init_glyph_path(cairo_dwrite_scaled_font_t *scaled_fon
|
|||
FLOAT advance = 0.0;
|
||||
cairo_dwrite_font_face_t *dwriteff = (cairo_dwrite_font_face_t*)scaled_font->base.font_face;
|
||||
|
||||
/* GetGlyphRunOutline seems to ignore hinting so just use the em size to get the outline
|
||||
* to avoid rounding errors when converting to cairo_path_fixed_t.
|
||||
*/
|
||||
DWRITE_FONT_METRICS metrics;
|
||||
dwriteff->dwriteface->GetMetrics(&metrics);
|
||||
HRESULT hr = dwriteff->dwriteface->GetGlyphRunOutline(metrics.designUnitsPerEm,
|
||||
HRESULT hr = dwriteff->dwriteface->GetGlyphRunOutline(1,
|
||||
&glyphId,
|
||||
&advance,
|
||||
&offset,
|
||||
|
|
@ -864,12 +878,6 @@ _cairo_dwrite_scaled_font_init_glyph_path(cairo_dwrite_scaled_font_t *scaled_fon
|
|||
|
||||
status = (cairo_int_status_t)_cairo_path_fixed_close_path(path);
|
||||
|
||||
/* Now scale the em size down to 1.0 and apply the font matrix and font ctm. */
|
||||
cairo_matrix_t mat = scaled_font->base.ctm;
|
||||
cairo_matrix_multiply(&mat, &scaled_font->base.font_matrix, &mat);
|
||||
cairo_matrix_scale (&mat, 1.0/metrics.designUnitsPerEm, 1.0/metrics.designUnitsPerEm);
|
||||
_cairo_path_fixed_transform(path, &mat);
|
||||
|
||||
_cairo_scaled_glyph_set_path (scaled_glyph,
|
||||
&scaled_font->base,
|
||||
path);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue