Bug 717393 - Part 1: Add helper for creating DWriteGlyphRuns. r=jrmuizel

This commit is contained in:
Bas Schouten 2012-05-15 16:57:51 +02:00
parent 870387f59e
commit 98d653e97b
3 changed files with 78 additions and 29 deletions

View File

@ -910,34 +910,11 @@ DrawTargetD2D::FillGlyphs(ScaledFont *aFont,
RefPtr<ID2D1Brush> brush = CreateBrushForPattern(aPattern, aOptions.mAlpha);
DWRITE_GLYPH_RUN glyphRun;
glyphRun.bidiLevel = 0;
glyphRun.fontEmSize = font->mSize;
glyphRun.isSideways = FALSE;
glyphRun.fontFace = font->mFontFace;
glyphRun.glyphCount = aBuffer.mNumGlyphs;
std::vector<UINT16> indices;
std::vector<FLOAT> advances;
std::vector<DWRITE_GLYPH_OFFSET> offsets;
indices.resize(aBuffer.mNumGlyphs);
advances.resize(aBuffer.mNumGlyphs);
offsets.resize(aBuffer.mNumGlyphs);
memset(&advances.front(), 0, sizeof(FLOAT) * aBuffer.mNumGlyphs);
for (unsigned int i = 0; i < aBuffer.mNumGlyphs; i++) {
indices[i] = aBuffer.mGlyphs[i].mIndex;
offsets[i].advanceOffset = aBuffer.mGlyphs[i].mPosition.x;
offsets[i].ascenderOffset = -aBuffer.mGlyphs[i].mPosition.y;
}
glyphRun.glyphAdvances = &advances.front();
glyphRun.glyphIndices = &indices.front();
glyphRun.glyphOffsets = &offsets.front();
AutoDWriteGlyphRun autoRun;
DWriteGlyphRunFromGlyphs(aBuffer, font, &autoRun);
if (brush) {
rt->DrawGlyphRun(D2D1::Point2F(), &glyphRun, brush);
rt->DrawGlyphRun(D2D1::Point2F(), &autoRun, brush);
}
FinalizeRTForOperation(aOptions.mCompositionOp, aPattern, Rect(0, 0, (Float)mSize.width, (Float)mSize.height));

View File

@ -39,8 +39,11 @@
#define MOZILLA_GFX_HELPERSD2D_H_
#include <d2d1.h>
#include <dwrite.h>
#include "2D.h"
#include "ScaledFontDWrite.h"
namespace mozilla {
namespace gfx {
@ -212,6 +215,78 @@ struct ShaderConstantRectD3D10
operator float* () { return &mX; }
};
static DWRITE_MATRIX
DWriteMatrixFromMatrix(Matrix &aMatrix)
{
DWRITE_MATRIX mat;
mat.m11 = aMatrix._11;
mat.m12 = aMatrix._12;
mat.m21 = aMatrix._21;
mat.m22 = aMatrix._22;
mat.dx = aMatrix._31;
mat.dy = aMatrix._32;
return mat;
}
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];
};
static void
DWriteGlyphRunFromGlyphs(const GlyphBuffer &aGlyphs, ScaledFontDWrite *aFont, AutoDWriteGlyphRun *run)
{
run->allocate(aGlyphs.mNumGlyphs);
FLOAT *advances = const_cast<FLOAT*>(run->glyphAdvances);
UINT16 *indices = const_cast<UINT16*>(run->glyphIndices);
DWRITE_GLYPH_OFFSET *offsets = const_cast<DWRITE_GLYPH_OFFSET*>(run->glyphOffsets);
memset(advances, 0, sizeof(FLOAT) * aGlyphs.mNumGlyphs);
for (unsigned int i = 0; i < aGlyphs.mNumGlyphs; i++) {
indices[i] = aGlyphs.mGlyphs[i].mIndex;
offsets[i].advanceOffset = aGlyphs.mGlyphs[i].mPosition.x;
offsets[i].ascenderOffset = -aGlyphs.mGlyphs[i].mPosition.y;
}
run->bidiLevel = 0;
run->fontFace = aFont->mFontFace;
run->fontEmSize = aFont->mSize;
run->glyphCount = aGlyphs.mNumGlyphs;
run->isSideways = FALSE;
}
}
}

View File

@ -59,9 +59,6 @@ public:
virtual TemporaryRef<Path> GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget *aTarget);
virtual void CopyGlyphsToBuilder(const GlyphBuffer &aBuffer, PathBuilder *aBuilder);
private:
friend class DrawTargetD2D;
void CopyGlyphsToSink(const GlyphBuffer &aBuffer, ID2D1GeometrySink *aSink);
RefPtr<IDWriteFontFace> mFontFace;