mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
bug 721511 - use stack-based buffers for moderate-sized glyph runs in cairo/dwrite backend. r=bas
This commit is contained in:
parent
ad4fa54177
commit
7f9bb5f2a6
@ -3674,7 +3674,7 @@ _cairo_dwrite_manual_show_glyphs_on_d2d_surface(void *surface,
|
||||
_cairo_d2d_set_clip(dst, NULL);
|
||||
dst->rt->Flush();
|
||||
|
||||
DWRITE_GLYPH_RUN run;
|
||||
AutoDWriteGlyphRun run;
|
||||
_cairo_dwrite_glyph_run_from_glyphs(glyphs, num_glyphs, scaled_font, &run, &transform);
|
||||
|
||||
RefPtr<IDWriteGlyphRunAnalysis> analysis;
|
||||
@ -3731,9 +3731,6 @@ _cairo_dwrite_manual_show_glyphs_on_d2d_surface(void *surface,
|
||||
0,
|
||||
0,
|
||||
&analysis);
|
||||
delete [] run.glyphIndices;
|
||||
delete [] run.glyphAdvances;
|
||||
delete [] run.glyphOffsets;
|
||||
if (FAILED(hr)) {
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
@ -4105,8 +4102,7 @@ _cairo_dwrite_show_glyphs_on_d2d_surface(void *surface,
|
||||
|
||||
cairo_bool_t transform = FALSE;
|
||||
|
||||
DWRITE_GLYPH_RUN run;
|
||||
|
||||
AutoDWriteGlyphRun run;
|
||||
_cairo_dwrite_glyph_run_from_glyphs(glyphs, num_glyphs, dwritesf, &run, &transform);
|
||||
|
||||
D2D1::Matrix3x2F mat = _cairo_d2d_matrix_from_matrix(&dwritesf->mat);
|
||||
@ -4141,9 +4137,6 @@ _cairo_dwrite_show_glyphs_on_d2d_surface(void *surface,
|
||||
source);
|
||||
|
||||
if (!brush) {
|
||||
delete [] run.glyphIndices;
|
||||
delete [] run.glyphOffsets;
|
||||
delete [] run.glyphAdvances;
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
@ -4165,10 +4158,6 @@ _cairo_dwrite_show_glyphs_on_d2d_surface(void *surface,
|
||||
target_rt->SetTransform(D2D1::Matrix3x2F::Identity());
|
||||
}
|
||||
|
||||
delete [] run.glyphIndices;
|
||||
delete [] run.glyphOffsets;
|
||||
delete [] run.glyphAdvances;
|
||||
|
||||
if (target_rt.get() != dst->rt.get()) {
|
||||
return _cairo_d2d_blend_temp_surface(dst, op, target_rt, clip, &fontArea);
|
||||
}
|
||||
|
@ -336,12 +336,14 @@ void
|
||||
_cairo_dwrite_glyph_run_from_glyphs(cairo_glyph_t *glyphs,
|
||||
int num_glyphs,
|
||||
cairo_dwrite_scaled_font_t *scaled_font,
|
||||
DWRITE_GLYPH_RUN *run,
|
||||
AutoDWriteGlyphRun *run,
|
||||
cairo_bool_t *transformed)
|
||||
{
|
||||
UINT16 *indices = new UINT16[num_glyphs];
|
||||
FLOAT *advances = new FLOAT[num_glyphs];
|
||||
DWRITE_GLYPH_OFFSET *offsets = new DWRITE_GLYPH_OFFSET[num_glyphs];
|
||||
run->allocate(num_glyphs);
|
||||
|
||||
UINT16 *indices = const_cast<UINT16*>(run->glyphIndices);
|
||||
FLOAT *advances = const_cast<FLOAT*>(run->glyphAdvances);
|
||||
DWRITE_GLYPH_OFFSET *offsets = const_cast<DWRITE_GLYPH_OFFSET*>(run->glyphOffsets);
|
||||
|
||||
cairo_dwrite_font_face_t *dwriteff = reinterpret_cast<cairo_dwrite_font_face_t*>(scaled_font->base.font_face);
|
||||
|
||||
@ -349,9 +351,6 @@ _cairo_dwrite_glyph_run_from_glyphs(cairo_glyph_t *glyphs,
|
||||
run->fontFace = dwriteff->dwriteface;
|
||||
run->glyphCount = num_glyphs;
|
||||
run->isSideways = FALSE;
|
||||
run->glyphIndices = indices;
|
||||
run->glyphOffsets = offsets;
|
||||
run->glyphAdvances = advances;
|
||||
|
||||
if (scaled_font->mat.xy == 0 && scaled_font->mat.yx == 0 &&
|
||||
scaled_font->mat.xx == scaled_font->base.font_matrix.xx &&
|
||||
@ -598,19 +597,17 @@ _cairo_dwrite_scaled_show_glyphs(void *scaled_font,
|
||||
} else {
|
||||
cairo_dwrite_scaled_font_t *dwritesf =
|
||||
static_cast<cairo_dwrite_scaled_font_t*>(scaled_font);
|
||||
UINT16 *indices = new UINT16[num_glyphs];
|
||||
DWRITE_GLYPH_OFFSET *offsets = new DWRITE_GLYPH_OFFSET[num_glyphs];
|
||||
FLOAT *advances = new FLOAT[num_glyphs];
|
||||
BOOL transform = FALSE;
|
||||
|
||||
DWRITE_GLYPH_RUN run;
|
||||
AutoDWriteGlyphRun run;
|
||||
run.allocate(num_glyphs);
|
||||
UINT16 *indices = const_cast<UINT16*>(run.glyphIndices);
|
||||
FLOAT *advances = const_cast<FLOAT*>(run.glyphAdvances);
|
||||
DWRITE_GLYPH_OFFSET *offsets = const_cast<DWRITE_GLYPH_OFFSET*>(run.glyphOffsets);
|
||||
|
||||
run.bidiLevel = 0;
|
||||
run.fontFace = ((cairo_dwrite_font_face_t*)dwritesf->base.font_face)->dwriteface;
|
||||
run.glyphIndices = indices;
|
||||
run.glyphCount = num_glyphs;
|
||||
run.isSideways = FALSE;
|
||||
run.glyphOffsets = offsets;
|
||||
run.glyphAdvances = advances;
|
||||
IDWriteGlyphRunAnalysis *analysis;
|
||||
|
||||
if (dwritesf->mat.xy == 0 && dwritesf->mat.yx == 0 &&
|
||||
@ -1285,9 +1282,13 @@ _cairo_dwrite_show_glyphs_on_surface(void *surface,
|
||||
* coordinate due to accumulated rounding error. As a result strings could
|
||||
* be painted shorter or longer than expected. */
|
||||
|
||||
UINT16 *indices = new UINT16[num_glyphs];
|
||||
DWRITE_GLYPH_OFFSET *offsets = new DWRITE_GLYPH_OFFSET[num_glyphs];
|
||||
FLOAT *advances = new FLOAT[num_glyphs];
|
||||
AutoDWriteGlyphRun run;
|
||||
run.allocate(num_glyphs);
|
||||
|
||||
UINT16 *indices = const_cast<UINT16*>(run.glyphIndices);
|
||||
FLOAT *advances = const_cast<FLOAT*>(run.glyphAdvances);
|
||||
DWRITE_GLYPH_OFFSET *offsets = const_cast<DWRITE_GLYPH_OFFSET*>(run.glyphOffsets);
|
||||
|
||||
BOOL transform = FALSE;
|
||||
/* Needed to calculate bounding box for efficient blitting */
|
||||
INT32 smallestX = INT_MAX;
|
||||
@ -1343,14 +1344,9 @@ _cairo_dwrite_show_glyphs_on_surface(void *surface,
|
||||
fontArea.bottom = dst->extents.height;
|
||||
}
|
||||
|
||||
DWRITE_GLYPH_RUN run;
|
||||
run.bidiLevel = 0;
|
||||
run.fontFace = dwriteff->dwriteface;
|
||||
run.glyphIndices = indices;
|
||||
run.glyphCount = num_glyphs;
|
||||
run.isSideways = FALSE;
|
||||
run.glyphOffsets = offsets;
|
||||
run.glyphAdvances = advances;
|
||||
if (dwritesf->mat.xy == 0 && dwritesf->mat.yx == 0 &&
|
||||
dwritesf->mat.xx == scaled_font->font_matrix.xx &&
|
||||
dwritesf->mat.yy == scaled_font->font_matrix.yy) {
|
||||
@ -1424,10 +1420,6 @@ _cairo_dwrite_show_glyphs_on_surface(void *surface,
|
||||
}
|
||||
#endif
|
||||
|
||||
delete [] indices;
|
||||
delete [] offsets;
|
||||
delete [] advances;
|
||||
|
||||
return CAIRO_INT_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -169,6 +169,42 @@ private:
|
||||
static int mRenderingMode;
|
||||
};
|
||||
|
||||
class AutoDWriteGlyphRun : public DWRITE_GLYPH_RUN
|
||||
{
|
||||
static const int kNumAutoGlyphs = 256;
|
||||
|
||||
public:
|
||||
AutoDWriteGlyphRun() {
|
||||
glyphCount = 0;
|
||||
}
|
||||
|
||||
~AutoDWriteGlyphRun() {
|
||||
if (glyphCount > kNumAutoGlyphs) {
|
||||
delete[] glyphIndices;
|
||||
delete[] glyphAdvances;
|
||||
delete[] glyphOffsets;
|
||||
}
|
||||
}
|
||||
|
||||
void allocate(int aNumGlyphs) {
|
||||
glyphCount = aNumGlyphs;
|
||||
if (aNumGlyphs <= kNumAutoGlyphs) {
|
||||
glyphIndices = &mAutoIndices[0];
|
||||
glyphAdvances = &mAutoAdvances[0];
|
||||
glyphOffsets = &mAutoOffsets[0];
|
||||
} else {
|
||||
glyphIndices = new UINT16[aNumGlyphs];
|
||||
glyphAdvances = new FLOAT[aNumGlyphs];
|
||||
glyphOffsets = new DWRITE_GLYPH_OFFSET[aNumGlyphs];
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
DWRITE_GLYPH_OFFSET mAutoOffsets[kNumAutoGlyphs];
|
||||
FLOAT mAutoAdvances[kNumAutoGlyphs];
|
||||
UINT16 mAutoIndices[kNumAutoGlyphs];
|
||||
};
|
||||
|
||||
/* cairo_font_face_t implementation */
|
||||
struct _cairo_dwrite_font_face {
|
||||
cairo_font_face_t base;
|
||||
@ -179,12 +215,10 @@ typedef struct _cairo_dwrite_font_face cairo_dwrite_font_face_t;
|
||||
|
||||
DWRITE_MATRIX _cairo_dwrite_matrix_from_matrix(const cairo_matrix_t *matrix);
|
||||
|
||||
// This will create a DWrite glyph run from cairo glyphs and a scaled_font.
|
||||
// It is important to note the array members of DWRITE_GLYPH_RUN should be
|
||||
// deleted by the caller.
|
||||
// This will initialize a DWrite glyph run from cairo glyphs and a scaled_font.
|
||||
void
|
||||
_cairo_dwrite_glyph_run_from_glyphs(cairo_glyph_t *glyphs,
|
||||
int num_glyphs,
|
||||
cairo_dwrite_scaled_font_t *scaled_font,
|
||||
DWRITE_GLYPH_RUN *run,
|
||||
AutoDWriteGlyphRun *run,
|
||||
cairo_bool_t *transformed);
|
||||
|
Loading…
Reference in New Issue
Block a user