Пример #1
0
glyph_metrics_t QFontEngineDirectWrite::alphaMapBoundingBox(glyph_t glyph, QFixed subPixelPosition,
                                                            const QTransform &matrix,
                                                            GlyphFormat /*format*/)
{
    glyph_metrics_t bbox = QFontEngine::boundingBox(glyph, matrix); // To get transformed advance

    UINT16 glyphIndex = glyph;
    FLOAT glyphAdvance = 0;

    DWRITE_GLYPH_OFFSET glyphOffset;
    glyphOffset.advanceOffset = 0;
    glyphOffset.ascenderOffset = 0;

    DWRITE_GLYPH_RUN glyphRun;
    glyphRun.fontFace = m_directWriteFontFace;
    glyphRun.fontEmSize = fontDef.pixelSize;
    glyphRun.glyphCount = 1;
    glyphRun.glyphIndices = &glyphIndex;
    glyphRun.glyphAdvances = &glyphAdvance;
    glyphRun.isSideways = false;
    glyphRun.bidiLevel = 0;
    glyphRun.glyphOffsets = &glyphOffset;

    DWRITE_MATRIX transform;
    transform.dx = subPixelPosition.toReal();
    transform.dy = 0;
    transform.m11 = matrix.m11();
    transform.m12 = matrix.m12();
    transform.m21 = matrix.m21();
    transform.m22 = matrix.m22();

    IDWriteGlyphRunAnalysis *glyphAnalysis = NULL;
    HRESULT hr = m_directWriteFactory->CreateGlyphRunAnalysis(
                &glyphRun,
                1.0f,
                &transform,
                DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC,
                DWRITE_MEASURING_MODE_NATURAL,
                0.0, 0.0,
                &glyphAnalysis
                );

    if (SUCCEEDED(hr)) {
        RECT rect;
        glyphAnalysis->GetAlphaTextureBounds(DWRITE_TEXTURE_CLEARTYPE_3x1, &rect);
        glyphAnalysis->Release();

        return glyph_metrics_t(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
                               bbox.xoff, bbox.yoff);
    } else {
        return glyph_metrics_t();
    }
}
STDMETHODIMP CustomDWriteRender::DrawGlyphRun( __maybenull void* clientDrawingContext, FLOAT baselineOriginX, FLOAT baselineOriginY, DWRITE_MEASURING_MODE measuringMode, __in DWRITE_GLYPH_RUN const* glyphRun, __in DWRITE_GLYPH_RUN_DESCRIPTION const* glyphRunDescription, __maybenull IUnknown* clientDrawingEffect )
{
	
	HRESULT hr;
	IDWriteGlyphRunAnalysis* glyphRunAnalysis;
	DWTextBox::DWTBContext* ctx = static_cast<DWTextBox::DWTBContext*>(clientDrawingContext);
	ci::Surface* finalSurface = ctx->surface;
	RECT textureBounds;
	hr = mDWriteFactory->CreateGlyphRunAnalysis(glyphRun,0.75f,NULL,DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC,DWRITE_MEASURING_MODE_GDI_CLASSIC,0.0f,0.0f,&glyphRunAnalysis);
	if(hr!=S_OK)
	{
		OutputDebugString(L"Error!\n");
	}

	glyphRunAnalysis->GetAlphaTextureBounds(DWRITE_TEXTURE_CLEARTYPE_3x1,&textureBounds);
	int width = textureBounds.right-textureBounds.left;
	int height = textureBounds.bottom -textureBounds.top;

	ci::Surface surface(width,height,true,ci::SurfaceChannelOrder::ARGB);
	//surface.setPremultiplied(true);
	uint8_t *dataAlpha = static_cast<uint8_t*>(malloc(width*height*4));
	uint8_t *data = static_cast<uint8_t*>(malloc(width*height*3));
	DWRITE_FONT_METRICS fontMetrics;
	glyphRun->fontFace->GetMetrics(&fontMetrics);
	glyphRunAnalysis->CreateAlphaTexture(DWRITE_TEXTURE_CLEARTYPE_3x1,&textureBounds,data,width*height*3);
	Concurrency::parallel_for(0,width*height,[&](int i){
		float combAlpha = (data[i*3] + data[i*3+1] +data[i*3+2])/3;
		float scale = combAlpha/255;

		dataAlpha[i*4+0] = combAlpha;
		
		dataAlpha[i*4+1] = 255*scale;//data[i*3+0];
		dataAlpha[i*4+2] = 255*scale;//data[i*3+0];
		dataAlpha[i*4+3] = 255*scale;//data[i*3+0];
		//dataAlpha[i*4+0] = (data[i*3] + data[i*3+1] +data[i*3+2])/3;
	});
	memcpy(surface.getData(),dataAlpha,width*height*4);
	float ratio = (float)(glyphRun->fontEmSize)/(float)fontMetrics.designUnitsPerEm;
	float ascend = surface.getBounds().y2 + fontMetrics.descent*ratio;
	
	//finalSurface->copyFrom(surface,surface.getBounds(),Vec2i(baselineOriginX,baselineOriginY-ascend));
	ci::ip::blend(finalSurface,surface,surface.getBounds(),Vec2i(baselineOriginX+textureBounds.left,baselineOriginY+textureBounds.top));
	//mTexture = gl::Texture(surface);
	free (data);
	free (dataAlpha);
	return S_OK;
}
Пример #3
0
QImage QFontEngineDirectWrite::imageForGlyph(glyph_t t,
                                             QFixed subPixelPosition,
                                             int margin,
                                             const QTransform &xform)
{
    UINT16 glyphIndex = t;
    FLOAT glyphAdvance = 0;

    DWRITE_GLYPH_OFFSET glyphOffset;
    glyphOffset.advanceOffset = 0;
    glyphOffset.ascenderOffset = 0;

    DWRITE_GLYPH_RUN glyphRun;
    glyphRun.fontFace = m_directWriteFontFace;
    glyphRun.fontEmSize = fontDef.pixelSize;
    glyphRun.glyphCount = 1;
    glyphRun.glyphIndices = &glyphIndex;
    glyphRun.glyphAdvances = &glyphAdvance;
    glyphRun.isSideways = false;
    glyphRun.bidiLevel = 0;
    glyphRun.glyphOffsets = &glyphOffset;

    DWRITE_MATRIX transform;
    transform.dx = subPixelPosition.toReal();
    transform.dy = 0;
    transform.m11 = xform.m11();
    transform.m12 = xform.m12();
    transform.m21 = xform.m21();
    transform.m22 = xform.m22();

    IDWriteGlyphRunAnalysis *glyphAnalysis = NULL;
    HRESULT hr = m_directWriteFactory->CreateGlyphRunAnalysis(
                &glyphRun,
                1.0f,
                &transform,
                DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC,
                DWRITE_MEASURING_MODE_NATURAL,
                0.0, 0.0,
                &glyphAnalysis
                );

    if (SUCCEEDED(hr)) {
        RECT rect;
        glyphAnalysis->GetAlphaTextureBounds(DWRITE_TEXTURE_CLEARTYPE_3x1, &rect);

        rect.left -= margin;
        rect.top -= margin;
        rect.right += margin;
        rect.bottom += margin;

        int width = rect.right - rect.left;
        int height = rect.bottom - rect.top;

        int size = width * height * 3;
        if (size > 0) {
            BYTE *alphaValues = new BYTE[size];
            qMemSet(alphaValues, size, 0);

            hr = glyphAnalysis->CreateAlphaTexture(DWRITE_TEXTURE_CLEARTYPE_3x1,
                                                   &rect,
                                                   alphaValues,
                                                   size);

            if (SUCCEEDED(hr)) {
                QImage img(width, height, QImage::Format_RGB32);
                img.fill(0xffffffff);

                for (int y=0; y<height; ++y) {
                    uint *dest = reinterpret_cast<uint *>(img.scanLine(y));
                    BYTE *src = alphaValues + width * 3 * y;

                    for (int x=0; x<width; ++x) {
                        dest[x] = *(src) << 16
                                | *(src + 1) << 8
                                | *(src + 2);

                        src += 3;
                    }
                }

                delete[] alphaValues;
                glyphAnalysis->Release();

                return img;
            } else {
                delete[] alphaValues;
                glyphAnalysis->Release();

                qErrnoWarning("QFontEngineDirectWrite::imageForGlyph: CreateAlphaTexture failed");
            }
        }
    } else {
        qErrnoWarning("QFontEngineDirectWrite::imageForGlyph: CreateGlyphRunAnalysis failed");
    }

    return QImage();
}