bug 642589 - expose prefs for tweaking DirectWrite/D2D antialiasing behavior. r=jdaggett

This commit is contained in:
Jonathan Kew 2011-04-21 07:29:50 +01:00
parent 816d0ec482
commit 8e92dd97a6
12 changed files with 436 additions and 180 deletions

View File

@ -80,7 +80,7 @@ typedef struct _cairo_d2d_device cairo_d2d_device_t;
struct _cairo_d2d_surface {
_cairo_d2d_surface() : d2d_clip(NULL), clipping(false), isDrawing(false),
textRenderingInit(true)
textRenderingInit(false)
{
_cairo_clip_init (&this->clip);
}

View File

@ -176,7 +176,7 @@ cairo_d2d_create_device_from_d3d10device(ID3D10Device1 *d3d10device)
CD3D10_BUFFER_DESC bufferDesc(sizeof(vertices), D3D10_BIND_VERTEX_BUFFER);
D3D10_SUBRESOURCE_DATA data;
CD3D10_TEXTURE2D_DESC textDesc(DXGI_FORMAT_B8G8R8A8_UNORM,
TEXT_TEXTURE_WIDTH,
TEXT_TEXTURE_WIDTH,
TEXT_TEXTURE_HEIGHT,
1, 1);
@ -352,10 +352,10 @@ cairo_release_device(cairo_device_t *device)
if (!newrefcnt) {
// Call the correct destructor
cairo_d2d_device_t *d2d_device = reinterpret_cast<cairo_d2d_device_t*>(device);
HMODULE d3d10_1 = d2d_device->mD3D10_1;
HMODULE d3d10_1 = d2d_device->mD3D10_1;
delete d2d_device;
_cairo_d2d_release_factory();
FreeLibrary(d3d10_1);
FreeLibrary(d3d10_1);
}
return newrefcnt;
}
@ -779,7 +779,7 @@ _cairo_d2d_get_buffer_texture(cairo_d2d_surface_t *surface)
surface->surface->QueryInterface(&surf);
surf->GetDesc(&surfDesc);
CD3D10_TEXTURE2D_DESC softDesc(surfDesc.Format, surfDesc.Width, surfDesc.Height);
softDesc.MipLevels = 1;
softDesc.MipLevels = 1;
softDesc.Usage = D3D10_USAGE_DEFAULT;
softDesc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
surface->device->mD3D10Device->CreateTexture2D(&softDesc, NULL, &surface->bufferTexture);
@ -1158,9 +1158,9 @@ _cairo_d2d_create_strokestyle_for_stroke_style(const cairo_stroke_style_t *style
(FLOAT)style->miter_limit,
dashStyle,
(FLOAT)style->dash_offset),
dashes,
style->num_dashes,
&strokeStyle);
dashes,
style->num_dashes,
&strokeStyle);
delete [] dashes;
return strokeStyle;
}
@ -1225,7 +1225,7 @@ static void _d2d_snapshot_detached(cairo_surface_t *surface)
}
if (!--existingBitmap->refs) {
cache_usage -= _d2d_compute_bitmap_mem_size(existingBitmap->bitmap);
delete existingBitmap;
delete existingBitmap;
}
cairo_surface_destroy(surface);
}
@ -1463,8 +1463,8 @@ _cairo_d2d_create_radial_gradient_brush(cairo_d2d_surface_t *d2dsurf,
} else if (source_pattern->base.base.extend == CAIRO_EXTEND_NONE) {
float offset_factor = (outer_radius - inner_radius) / outer_radius;
float global_offset = inner_radius / outer_radius;
num_stops++; // Add a stop on the outer radius.
num_stops++; // Add a stop on the outer radius.
if (inner_radius != 0) {
num_stops++; // Add a stop on the inner radius.
}
@ -1572,11 +1572,11 @@ _cairo_d2d_create_linear_gradient_brush(cairo_d2d_surface_t *d2dsurf,
double max_dist, min_dist;
max_dist = MAX(_cairo_d2d_dot_product(u, _cairo_d2d_subtract_point(top_left, p1)),
_cairo_d2d_dot_product(u, _cairo_d2d_subtract_point(top_right, p1)));
_cairo_d2d_dot_product(u, _cairo_d2d_subtract_point(top_right, p1)));
max_dist = MAX(max_dist, _cairo_d2d_dot_product(u, _cairo_d2d_subtract_point(bottom_left, p1)));
max_dist = MAX(max_dist, _cairo_d2d_dot_product(u, _cairo_d2d_subtract_point(bottom_right, p1)));
min_dist = MIN(_cairo_d2d_dot_product(u, _cairo_d2d_subtract_point(top_left, p1)),
_cairo_d2d_dot_product(u, _cairo_d2d_subtract_point(top_right, p1)));
_cairo_d2d_dot_product(u, _cairo_d2d_subtract_point(top_right, p1)));
min_dist = MIN(min_dist, _cairo_d2d_dot_product(u, _cairo_d2d_subtract_point(bottom_left, p1)));
min_dist = MIN(min_dist, _cairo_d2d_dot_product(u, _cairo_d2d_subtract_point(bottom_right, p1)));
@ -1758,7 +1758,7 @@ _cairo_d2d_create_brush_for_pattern(cairo_d2d_surface_t *d2dsurf,
*/
return NULL;
}
if (srcSurf->device != d2dsurf->device) {
if (srcSurf->device != d2dsurf->device) {
/* This code does not work if the source surface does not use
* the same device. Some work could be done to do something
* fairly efficient here, for now, fallback.
@ -1830,7 +1830,7 @@ _cairo_d2d_create_brush_for_pattern(cairo_d2d_surface_t *d2dsurf,
/* First we check which part of the image is inside the viewable area. */
_cairo_d2d_calculate_visible_rect(d2dsurf, srcSurf, &mat, &xoffset, &yoffset, &width, &height);
cairo_matrix_translate(&mat, xoffset, yoffset);
cairo_matrix_translate(&mat, xoffset, yoffset);
if (width > maxSize || height > maxSize) {
/*
@ -1840,11 +1840,11 @@ _cairo_d2d_create_brush_for_pattern(cairo_d2d_surface_t *d2dsurf,
* We need to size it to at least the diagonal size of this surface, in order to prevent ever
* upsampling this again when drawing it to the surface. We want the resized surface
* to be as small as possible to limit pixman required fill rate.
*
* Note this isn't necessarily perfect. Imagine having a 5x5 pixel destination and
* a 10x5 image containing a line of blackpixels, white pixels, black pixels, if you rotate
* this by 45 degrees and scale it to a size of 5x5 pixels and composite it to the destination,
* the composition will require all 10 original columns to do the best possible sampling.
*
* Note this isn't necessarily perfect. Imagine having a 5x5 pixel destination and
* a 10x5 image containing a line of blackpixels, white pixels, black pixels, if you rotate
* this by 45 degrees and scale it to a size of 5x5 pixels and composite it to the destination,
* the composition will require all 10 original columns to do the best possible sampling.
*/
RefPtr<IDXGISurface> surf;
d2dsurf->surface->QueryInterface(&surf);
@ -1978,10 +1978,10 @@ _cairo_d2d_create_brush_for_pattern(cairo_d2d_surface_t *d2dsurf,
cachebitmap->dirty = false;
cachebitmap->bitmap = sourceBitmap;
cachebitmap->device = d2dsurf->device;
/*
* This will start out with two references, one on the snapshot
* and one more in the user data structure.
*/
/*
* This will start out with two references, one on the snapshot
* and one more in the user data structure.
*/
cachebitmap->refs = 2;
cairo_surface_set_user_data(surfacePattern->surface,
key,
@ -2272,7 +2272,7 @@ _cairo_d2d_clear (cairo_d2d_surface_t *d2dsurf,
d2dsurf->rt->PushAxisAlignedClip(
D2D1::RectF((FLOAT)rect.x,
(FLOAT)rect.y,
(FLOAT)rect.y,
(FLOAT)rect.x + rect.width,
(FLOAT)rect.y + rect.height),
D2D1_ANTIALIAS_MODE_ALIASED);
@ -2288,7 +2288,7 @@ _cairo_d2d_clear (cairo_d2d_surface_t *d2dsurf,
}
static cairo_operator_t _cairo_d2d_simplify_operator(cairo_operator_t op,
const cairo_pattern_t *source)
const cairo_pattern_t *source)
{
if (op == CAIRO_OPERATOR_SOURCE) {
/** Operator over is easier for D2D! If the source if opaque, change */
@ -2655,7 +2655,7 @@ _cairo_d2d_copy_surface(cairo_d2d_surface_t *dst,
src->device->mD3D10Device->CopyResource(srcResource, src->surface);
} else {
// Need to flush the source too if it's a different surface.
_cairo_d2d_flush(src);
_cairo_d2d_flush(src);
}
// One copy for each rectangle in the final clipping region.
@ -2705,7 +2705,7 @@ _cairo_d2d_blend_surface(cairo_d2d_surface_t *dst,
const cairo_matrix_t *transform,
cairo_box_t *box,
cairo_clip_t *clip,
cairo_filter_t filter,
cairo_filter_t filter,
float opacity)
{
if (dst == src) {
@ -2804,12 +2804,12 @@ _cairo_d2d_blend_surface(cairo_d2d_surface_t *dst,
*/
static cairo_int_status_t
_cairo_d2d_try_fastblit(cairo_d2d_surface_t *dst,
cairo_surface_t *src,
cairo_box_t *box,
const cairo_matrix_t *matrix,
cairo_clip_t *clip,
cairo_operator_t op,
cairo_filter_t filter,
cairo_surface_t *src,
cairo_box_t *box,
const cairo_matrix_t *matrix,
cairo_clip_t *clip,
cairo_operator_t op,
cairo_filter_t filter,
float opacity = 1.0f)
{
if (op == CAIRO_OPERATOR_OVER && src->content == CAIRO_CONTENT_COLOR) {
@ -3102,8 +3102,8 @@ _cairo_d2d_paint(void *surface,
reinterpret_cast<const cairo_surface_pattern_t*>(source);
status = _cairo_d2d_try_fastblit(d2dsurf, surf_pattern->surface,
NULL, &source->matrix, clip,
op, source->filter);
NULL, &source->matrix, clip,
op, source->filter);
if (status != CAIRO_INT_STATUS_UNSUPPORTED) {
return status;
@ -3230,7 +3230,7 @@ _cairo_d2d_mask(void *surface,
&source->matrix,
clip,
op,
source->filter,
source->filter,
solidAlphaValue);
if (rv != CAIRO_INT_STATUS_UNSUPPORTED) {
return rv;
@ -3432,8 +3432,8 @@ _cairo_d2d_fill(void *surface,
const cairo_surface_pattern_t *surf_pattern =
reinterpret_cast<const cairo_surface_pattern_t*>(source);
cairo_int_status_t rv = _cairo_d2d_try_fastblit(d2dsurf, surf_pattern->surface,
&box, &source->matrix, clip, op,
source->filter);
&box, &source->matrix, clip, op,
source->filter);
if (rv != CAIRO_INT_STATUS_UNSUPPORTED) {
return rv;
@ -3583,7 +3583,11 @@ _cairo_dwrite_manual_show_glyphs_on_d2d_surface(void *surface,
}
// Deal with rendering modes CreateGlyphRunAnalysis doesn't accept.
if (renderMode == DWRITE_RENDERING_MODE_DEFAULT) {
switch (renderMode) {
case DWRITE_RENDERING_MODE_ALIASED:
// ClearType texture creation will fail in this mode, so bail out
return CAIRO_INT_STATUS_UNSUPPORTED;
case DWRITE_RENDERING_MODE_DEFAULT:
// As per DWRITE_RENDERING_MODE documentation, pick Natural for font
// sizes under 16 ppem
if (scaled_font->base.font_matrix.yy < 16.0f) {
@ -3591,15 +3595,24 @@ _cairo_dwrite_manual_show_glyphs_on_d2d_surface(void *surface,
} else {
renderMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC;
}
} else if (renderMode == DWRITE_RENDERING_MODE_OUTLINE) {
break;
case DWRITE_RENDERING_MODE_OUTLINE:
renderMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC;
break;
default:
break;
}
DWRITE_MEASURING_MODE measureMode =
renderMode <= DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC ? DWRITE_MEASURING_MODE_GDI_CLASSIC :
renderMode == DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL ? DWRITE_MEASURING_MODE_GDI_NATURAL :
DWRITE_MEASURING_MODE_NATURAL;
hr = DWriteFactory::Instance()->CreateGlyphRunAnalysis(&run,
1.0f,
transform ? &dwmat : 0,
renderMode,
DWRITE_MEASURING_MODE_NATURAL,
measureMode,
0,
0,
&analysis);
@ -3799,7 +3812,7 @@ _cairo_dwrite_manual_show_glyphs_on_d2d_surface(void *surface,
ID3D10EffectVectorVariable *textColor = effect->GetVariableByName("TextColor")->AsVector();
float colorVal[] = { float(source->color.red * source->color.alpha),
float(source->color.green * source->color.alpha),
float(source->color.green * source->color.alpha),
float(source->color.blue * source->color.alpha),
float(source->color.alpha) };
textColor->SetFloatVector(colorVal);
@ -3919,18 +3932,62 @@ _cairo_dwrite_show_glyphs_on_d2d_surface(void *surface,
cleartype_quality = D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE;
}
switch (dwritesf->antialias_mode) {
case CAIRO_ANTIALIAS_NONE:
target_rt->SetTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_ALIASED);
break;
case CAIRO_ANTIALIAS_GRAY:
target_rt->SetTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE);
break;
case CAIRO_ANTIALIAS_SUBPIXEL:
target_rt->SetTextAntialiasMode(cleartype_quality);
break;
RefPtr<IDWriteRenderingParams> params;
target_rt->GetTextRenderingParams(&params);
DWRITE_RENDERING_MODE renderMode = DWRITE_RENDERING_MODE_DEFAULT;
if (params) {
HRESULT hr = dwriteff->dwriteface->GetRecommendedRenderingMode(
(FLOAT)dwritesf->base.font_matrix.yy,
1.0f,
DWRITE_MEASURING_MODE_NATURAL,
params,
&renderMode);
if (FAILED(hr)) {
// this probably never happens, but let's play it safe
renderMode = DWRITE_RENDERING_MODE_DEFAULT;
}
}
// Deal with rendering modes CreateGlyphRunAnalysis doesn't accept
switch (renderMode) {
case DWRITE_RENDERING_MODE_DEFAULT:
// As per DWRITE_RENDERING_MODE documentation, pick Natural for font
// sizes under 16 ppem
if (dwritesf->base.font_matrix.yy < 16.0f) {
renderMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL;
} else {
renderMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC;
}
break;
case DWRITE_RENDERING_MODE_OUTLINE:
return CAIRO_INT_STATUS_UNSUPPORTED;
default:
break;
}
switch (dwritesf->antialias_mode) {
case CAIRO_ANTIALIAS_NONE:
cleartype_quality = D2D1_TEXT_ANTIALIAS_MODE_ALIASED;
break;
case CAIRO_ANTIALIAS_GRAY:
cleartype_quality = D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE;
break;
case CAIRO_ANTIALIAS_SUBPIXEL:
break;
}
if (renderMode == DWRITE_RENDERING_MODE_ALIASED) {
cleartype_quality = D2D1_TEXT_ANTIALIAS_MODE_ALIASED;
}
target_rt->SetTextAntialiasMode(cleartype_quality);
DWRITE_MEASURING_MODE measureMode =
renderMode <= DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC ? DWRITE_MEASURING_MODE_GDI_CLASSIC :
renderMode == DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL ? DWRITE_MEASURING_MODE_GDI_NATURAL :
DWRITE_MEASURING_MODE_NATURAL;
cairo_bool_t transform = FALSE;
DWRITE_GLYPH_RUN run;
@ -3949,8 +4006,8 @@ _cairo_dwrite_show_glyphs_on_d2d_surface(void *surface,
DWriteFactory::Instance()->CreateGlyphRunAnalysis(&run,
1.0f,
transform ? &dwmat : 0,
DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC,
DWRITE_MEASURING_MODE_NATURAL,
renderMode,
measureMode,
0,
0,
&analysis);
@ -3987,7 +4044,7 @@ _cairo_dwrite_show_glyphs_on_d2d_surface(void *surface,
brush->SetTransform(&mat_brush);
}
target_rt->DrawGlyphRun(D2D1::Point2F(0, 0), &run, brush, dwritesf->measuring_mode);
target_rt->DrawGlyphRun(D2D1::Point2F(0, 0), &run, brush, measureMode);
if (transform) {
target_rt->SetTransform(D2D1::Matrix3x2F::Identity());
@ -4019,14 +4076,13 @@ _cairo_d2d_show_glyphs (void *surface,
}
cairo_d2d_surface_t *d2dsurf = static_cast<cairo_d2d_surface_t*>(surface);
if (!d2dsurf->textRenderingInit) {
RefPtr<IDWriteRenderingParams> params;
DWriteFactory::Instance()->CreateRenderingParams(&params);
RefPtr<IDWriteRenderingParams> params = DWriteFactory::RenderingParams();
d2dsurf->rt->SetTextRenderingParams(params);
d2dsurf->textRenderingInit = true;
}
cairo_int_status_t status = CAIRO_INT_STATUS_UNSUPPORTED;
if (scaled_font->backend->type == CAIRO_FONT_TYPE_DWRITE) {
status = (cairo_int_status_t)
status = (cairo_int_status_t)
_cairo_dwrite_show_glyphs_on_d2d_surface(surface, op, source, glyphs, num_glyphs, scaled_font, clip);
}
@ -4131,7 +4187,7 @@ cairo_d2d_surface_create_for_hwnd(cairo_device_t *cairo_device,
}
/** Get the backbuffer surface from the swap chain */
hr = newSurf->dxgiChain->GetBuffer(0,
IID_PPV_ARGS(&newSurf->surface));
IID_PPV_ARGS(&newSurf->surface));
if (FAILED(hr)) {
goto FAIL_HWND;
@ -4176,8 +4232,8 @@ FAIL_HWND:
cairo_surface_t *
cairo_d2d_surface_create(cairo_device_t *device,
cairo_format_t format,
int width,
int height)
int width,
int height)
{
if (width == 0 || height == 0) {
return _cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_INVALID_SIZE));
@ -4474,7 +4530,7 @@ FAIL_CREATE:
void cairo_d2d_scroll(cairo_surface_t *surface, int x, int y, cairo_rectangle_t *clip)
{
if (surface->type != CAIRO_SURFACE_TYPE_D2D) {
return;
return;
}
cairo_d2d_surface_t *d2dsurf = reinterpret_cast<cairo_d2d_surface_t*>(surface);
@ -4537,7 +4593,7 @@ HDC
cairo_d2d_get_dc(cairo_surface_t *surface, cairo_bool_t retain_contents)
{
if (surface->type != CAIRO_SURFACE_TYPE_D2D) {
return NULL;
return NULL;
}
cairo_d2d_surface_t *d2dsurf = reinterpret_cast<cairo_d2d_surface_t*>(surface);
@ -4578,7 +4634,7 @@ void
cairo_d2d_release_dc(cairo_surface_t *surface, const cairo_rectangle_int_t *updated_rect)
{
if (surface->type != CAIRO_SURFACE_TYPE_D2D) {
return;
return;
}
cairo_d2d_surface_t *d2dsurf = reinterpret_cast<cairo_d2d_surface_t*>(surface);

View File

@ -119,6 +119,13 @@ private:
IDWriteFactory *DWriteFactory::mFactoryInstance = NULL;
IDWriteFontCollection *DWriteFactory::mSystemCollection = NULL;
IDWriteRenderingParams *DWriteFactory::mRenderingParams = NULL;
FLOAT DWriteFactory::mGamma = -1.0;
FLOAT DWriteFactory::mEnhancedContrast = -1.0;
FLOAT DWriteFactory::mClearTypeLevel = -1.0;
int DWriteFactory::mPixelGeometry = -1;
int DWriteFactory::mRenderingMode = -1;
ID2D1Factory *D2DFactory::mFactoryInstance = NULL;
ID2D1DCRenderTarget *D2DFactory::mRenderTarget = NULL;
@ -298,7 +305,6 @@ _cairo_dwrite_font_face_create_for_toy (cairo_toy_font_face_t *toy_face,
if (SUCCEEDED(hr)) {
// Cannot use C++ style new since cairo deallocates this.
*font_face = (cairo_font_face_t*)face;
_cairo_font_face_init (&(*(_cairo_dwrite_font_face**)font_face)->base, &_cairo_dwrite_font_face_backend);
} else {
free(face);
@ -349,7 +355,7 @@ _cairo_dwrite_glyph_run_from_glyphs(cairo_glyph_t *glyphs,
scaled_font->mat.xx == scaled_font->base.font_matrix.xx &&
scaled_font->mat.yy == scaled_font->base.font_matrix.yy) {
// Fast route, don't actually use a transform but just
// set the correct font size.
// set the correct font size.
*transformed = 0;
run->fontEmSize = (FLOAT)scaled_font->base.font_matrix.yy;
@ -371,14 +377,14 @@ _cairo_dwrite_glyph_run_from_glyphs(cairo_glyph_t *glyphs,
cairo_matrix_transform_point(&scaled_font->mat_inverse, &x, &y);
// Since we will multiply by our ctm matrix later for rotation effects
// and such, adjust positions by the inverse matrix now. Y-axis is
// inverted! Therefor the offset is -y.
// inverted! Therefor the offset is -y.
offsets[i].ascenderOffset = -(FLOAT)y;
offsets[i].advanceOffset = (FLOAT)x;
advances[i] = 0.0;
}
// The font matrix takes care of the scaling if we have a transform,
// emSize should be 1.
run->fontEmSize = 1.0f;
run->fontEmSize = 1.0f;
}
}
@ -715,22 +721,22 @@ _cairo_dwrite_scaled_font_init_glyph_metrics(cairo_dwrite_scaled_font_t *scaled_
// TODO: Treat swap_xy.
extents.width = (FLOAT)(metrics.advanceWidth - metrics.leftSideBearing - metrics.rightSideBearing) /
fontMetrics.designUnitsPerEm;
fontMetrics.designUnitsPerEm;
extents.height = (FLOAT)(metrics.advanceHeight - metrics.topSideBearing - metrics.bottomSideBearing) /
fontMetrics.designUnitsPerEm;
fontMetrics.designUnitsPerEm;
extents.x_advance = (FLOAT)metrics.advanceWidth / fontMetrics.designUnitsPerEm;
extents.x_bearing = (FLOAT)metrics.leftSideBearing / fontMetrics.designUnitsPerEm;
extents.y_advance = 0.0;
extents.y_bearing = (FLOAT)(metrics.topSideBearing - metrics.verticalOriginY) /
fontMetrics.designUnitsPerEm;
fontMetrics.designUnitsPerEm;
// We pad the extents here because GetDesignGlyphMetrics returns "ideal" metrics
// for the glyph outline, without accounting for hinting/gridfitting/antialiasing,
// and therefore it does not always cover all pixels that will actually be touched.
if (scaled_font->base.options.antialias != CAIRO_ANTIALIAS_NONE &&
extents.width > 0 && extents.height > 0) {
extents.width += scaled_font->mat_inverse.xx * 2;
extents.x_bearing -= scaled_font->mat_inverse.xx;
extents.width > 0 && extents.height > 0) {
extents.width += scaled_font->mat_inverse.xx * 2;
extents.x_bearing -= scaled_font->mat_inverse.xx;
}
_cairo_scaled_glyph_set_metrics (scaled_glyph,
@ -753,22 +759,22 @@ public:
// IUnknown interface
IFACEMETHOD(QueryInterface)(IID const& iid, OUT void** ppObject)
{
if (iid != __uuidof(IDWriteGeometrySink))
return E_NOINTERFACE;
if (iid != __uuidof(IDWriteGeometrySink))
return E_NOINTERFACE;
*ppObject = static_cast<IDWriteGeometrySink*>(this);
return S_OK;
return S_OK;
}
IFACEMETHOD_(ULONG, AddRef)()
{
return 1;
return 1;
}
IFACEMETHOD_(ULONG, Release)()
{
return 1;
return 1;
}
IFACEMETHODIMP_(void) SetFillMode(D2D1_FILL_MODE fillMode)
@ -822,7 +828,7 @@ public:
IFACEMETHODIMP_(void) AddBeziers(
const D2D1_BEZIER_SEGMENT *beziers,
UINT beziersCount)
UINT beziersCount)
{
for (unsigned int i = 0; i < beziersCount; i++) {
cairo_status_t status = _cairo_path_fixed_curve_to(mCairoPath,
@ -837,7 +843,7 @@ public:
IFACEMETHODIMP_(void) AddLines(
const D2D1_POINT_2F *points,
UINT pointsCount)
UINT pointsCount)
{
for (unsigned int i = 0; i < pointsCount; i++) {
cairo_status_t status = _cairo_path_fixed_line_to(mCairoPath,
@ -853,7 +859,7 @@ private:
cairo_int_status_t
_cairo_dwrite_scaled_font_init_glyph_path(cairo_dwrite_scaled_font_t *scaled_font,
cairo_scaled_glyph_t *scaled_glyph)
cairo_scaled_glyph_t *scaled_glyph)
{
cairo_path_fixed_t *path;
path = _cairo_path_fixed_create();
@ -999,8 +1005,8 @@ _cairo_dwrite_scaled_font_init_glyph_surface(cairo_dwrite_scaled_font_t *scaled_
cairo_surface_set_device_offset (image, -x1, -y1);
_cairo_scaled_glyph_set_surface (scaled_glyph,
&scaled_font->base,
(cairo_image_surface_t *) image);
&scaled_font->base,
(cairo_image_surface_t *) image);
FAIL:
cairo_surface_destroy (&surface->base);
@ -1009,7 +1015,7 @@ _cairo_dwrite_scaled_font_init_glyph_surface(cairo_dwrite_scaled_font_t *scaled_
}
cairo_int_status_t
_cairo_dwrite_load_truetype_table(void *scaled_font,
_cairo_dwrite_load_truetype_table(void *scaled_font,
unsigned long tag,
long offset,
unsigned char *buffer,
@ -1070,6 +1076,13 @@ cairo_dwrite_scaled_font_allow_manual_show_glyphs(void* dwrite_scaled_font, cair
font->manual_show_glyphs_allowed = allowed;
}
void
cairo_dwrite_set_cleartype_params(FLOAT gamma, FLOAT contrast, FLOAT level,
int geometry, int mode)
{
DWriteFactory::SetRenderingParams(gamma, contrast, level, geometry, mode);
}
cairo_int_status_t
_dwrite_draw_glyphs_to_gdi_surface_gdi(cairo_win32_surface_t *surface,
DWRITE_MATRIX *transform,
@ -1081,8 +1094,7 @@ _dwrite_draw_glyphs_to_gdi_surface_gdi(cairo_win32_surface_t *surface,
DWriteFactory::Instance()->GetGdiInterop(&gdiInterop);
IDWriteBitmapRenderTarget *rt;
IDWriteRenderingParams *params;
DWriteFactory::Instance()->CreateRenderingParams(&params);
IDWriteRenderingParams *params = DWriteFactory::RenderingParams();
gdiInterop->CreateBitmapRenderTarget(surface->dc,
area.right - area.left,
@ -1304,7 +1316,7 @@ _cairo_dwrite_show_glyphs_on_surface(void *surface,
offsets[i].advanceOffset = (FLOAT)(glyphs[i].x - fontArea.left);
advances[i] = 0.0;
}
run.fontEmSize = (FLOAT)scaled_font->font_matrix.yy;
run.fontEmSize = (FLOAT)scaled_font->font_matrix.yy;
} else {
transform = TRUE;
@ -1314,10 +1326,10 @@ _cairo_dwrite_show_glyphs_on_surface(void *surface,
double y = glyphs[i].y - fontArea.top;
cairo_matrix_transform_point(&dwritesf->mat_inverse, &x, &y);
/**
* Since we will multiply by our ctm matrix later for rotation effects
* Since we will multiply by our ctm matrix later for rotation effects
* and such, adjust positions by the inverse matrix now. The Y-axis
* is inverted so the offset becomes negative.
*/
* is inverted so the offset becomes negative.
*/
offsets[i].ascenderOffset = -(FLOAT)y;
offsets[i].advanceOffset = (FLOAT)x;
advances[i] = 0.0;
@ -1370,6 +1382,49 @@ _cairo_dwrite_show_glyphs_on_surface(void *surface,
return CAIRO_INT_STATUS_SUCCESS;
}
#define ENHANCED_CONTRAST_REGISTRY_KEY \
HKEY_CURRENT_USER, "Software\\Microsoft\\Avalon.Graphics\\DISPLAY1\\EnhancedContrastLevel"
void
DWriteFactory::CreateRenderingParams()
{
if (!Instance()) {
return;
}
RefPtr<IDWriteRenderingParams> defaultParams;
Instance()->CreateRenderingParams(&defaultParams);
// For EnhancedContrast, we override the default if the user has not set it
// in the registry (by using the ClearType Tuner).
FLOAT contrast;
if (mEnhancedContrast >= 0.0 && mEnhancedContrast <= 10.0) {
contrast = mEnhancedContrast;
} else {
HKEY hKey;
if (RegOpenKeyExA(ENHANCED_CONTRAST_REGISTRY_KEY,
0, KEY_READ, &hKey) == ERROR_SUCCESS)
{
contrast = defaultParams->GetEnhancedContrast();
RegCloseKey(hKey);
} else {
contrast = 1.0;
}
}
// For parameters that have not been explicitly set via the SetRenderingParams API,
// we copy values from default params (or our overridden value for contrast)
Instance()->CreateCustomRenderingParams(
mGamma >= 1.0 && mGamma <= 2.2 ? mGamma : defaultParams->GetGamma(),
contrast,
mClearTypeLevel >= 0.0 && mClearTypeLevel <= 1.0 ? mClearTypeLevel : defaultParams->GetClearTypeLevel(),
mPixelGeometry >= DWRITE_PIXEL_GEOMETRY_FLAT && mPixelGeometry <= DWRITE_PIXEL_GEOMETRY_BGR ?
(DWRITE_PIXEL_GEOMETRY)mPixelGeometry : defaultParams->GetPixelGeometry(),
mRenderingMode >= DWRITE_RENDERING_MODE_DEFAULT && mRenderingMode <= DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC ?
(DWRITE_RENDERING_MODE)mRenderingMode : defaultParams->GetRenderingMode(),
&mRenderingParams);
}
// Helper for _cairo_win32_printing_surface_show_glyphs to create a win32 equivalent
// of a dwrite scaled_font so that we can print using ExtTextOut instead of drawing
// paths or blitting glyph bitmaps.

View File

@ -92,9 +92,46 @@ public:
return family;
}
static IDWriteRenderingParams *RenderingParams()
{
if (!mRenderingParams) {
CreateRenderingParams();
}
if (mRenderingParams) {
mRenderingParams->AddRef();
}
return mRenderingParams;
}
static void SetRenderingParams(FLOAT aGamma,
FLOAT aEnhancedContrast,
FLOAT aClearTypeLevel,
int aPixelGeometry,
int aRenderingMode)
{
mGamma = aGamma;
mEnhancedContrast = aEnhancedContrast;
mClearTypeLevel = aClearTypeLevel;
mPixelGeometry = aPixelGeometry;
mRenderingMode = aRenderingMode;
// discard any current RenderingParams object
if (mRenderingParams) {
mRenderingParams->Release();
mRenderingParams = NULL;
}
}
private:
static void CreateRenderingParams();
static IDWriteFactory *mFactoryInstance;
static IDWriteFontCollection *mSystemCollection;
static IDWriteRenderingParams *mRenderingParams;
static FLOAT mGamma;
static FLOAT mEnhancedContrast;
static FLOAT mClearTypeLevel;
static int mPixelGeometry;
static int mRenderingMode;
};
/* cairo_font_face_t implementation */

View File

@ -126,6 +126,9 @@ cairo_dwrite_font_face_create_for_dwrite_fontface(void *dwrite_font, void *dwrit
void
cairo_dwrite_scaled_font_allow_manual_show_glyphs(void *dwrite_scaled_font, cairo_bool_t allowed);
void
cairo_dwrite_set_cleartype_params(FLOAT gamma, FLOAT contrast, FLOAT level, int geometry, int mode);
#endif /* CAIRO_HAS_DWRITE_FONT */
#if CAIRO_HAS_D2D_SURFACE

View File

@ -149,7 +149,10 @@ gfxDWriteFont::gfxDWriteFont(gfxFontEntry *aFontEntry,
return;
}
if ((anAAOption == gfxFont::kAntialiasDefault && UsingClearType()) ||
if ((anAAOption == gfxFont::kAntialiasDefault &&
UsingClearType() &&
(gfxWindowsPlatform::GetPlatform()->DWriteMeasuringMode() ==
DWRITE_MEASURING_MODE_NATURAL)) ||
anAAOption == gfxFont::kAntialiasSubpixel)
{
mUseSubpixelPositions = PR_TRUE;
@ -248,16 +251,12 @@ gfxDWriteFont::ComputeMetrics()
mMetrics = new gfxFont::Metrics;
::memset(mMetrics, 0, sizeof(*mMetrics));
mMetrics->xHeight =
((gfxFloat)fontMetrics.xHeight /
fontMetrics.designUnitsPerEm) * mAdjustedSize;
mFUnitsConvFactor = float(mAdjustedSize / fontMetrics.designUnitsPerEm);
mMetrics->maxAscent =
ceil(((gfxFloat)fontMetrics.ascent /
fontMetrics.designUnitsPerEm) * mAdjustedSize);
mMetrics->maxDescent =
ceil(((gfxFloat)fontMetrics.descent /
fontMetrics.designUnitsPerEm) * mAdjustedSize);
mMetrics->xHeight = fontMetrics.xHeight * mFUnitsConvFactor;
mMetrics->maxAscent = ceil(fontMetrics.ascent * mFUnitsConvFactor);
mMetrics->maxDescent = ceil(fontMetrics.descent * mFUnitsConvFactor);
mMetrics->maxHeight = mMetrics->maxAscent + mMetrics->maxDescent;
mMetrics->emHeight = mAdjustedSize;
@ -282,88 +281,72 @@ gfxDWriteFont::ComputeMetrics()
if (exists && len >= sizeof(mozilla::HheaTable)) {
const mozilla::HheaTable* hhea =
reinterpret_cast<const mozilla::HheaTable*>(tableData);
mMetrics->maxAdvance = ((gfxFloat)PRUint16(hhea->advanceWidthMax) /
fontMetrics.designUnitsPerEm) * mAdjustedSize;
mMetrics->maxAdvance =
PRUint16(hhea->advanceWidthMax) * mFUnitsConvFactor;
}
mFontFace->ReleaseFontTable(tableContext);
}
mMetrics->internalLeading = NS_MAX(mMetrics->maxHeight - mMetrics->emHeight, 0.0);
mMetrics->externalLeading =
ceil(((gfxFloat)fontMetrics.lineGap /
fontMetrics.designUnitsPerEm) * mAdjustedSize);
mMetrics->externalLeading = ceil(fontMetrics.lineGap * mFUnitsConvFactor);
UINT16 glyph = (PRUint16)GetSpaceGlyph();
DWRITE_GLYPH_METRICS metrics;
mFontFace->GetDesignGlyphMetrics(&glyph, 1, &metrics);
mMetrics->spaceWidth =
((gfxFloat)metrics.advanceWidth /
fontMetrics.designUnitsPerEm) * mAdjustedSize;
mMetrics->spaceWidth = MeasureGlyphWidth(glyph);
// try to get aveCharWidth from the OS/2 table, fall back to measuring 'x'
// if the table is not available
mMetrics->aveCharWidth = 0;
hr = mFontFace->TryGetFontTable(DWRITE_MAKE_OPENTYPE_TAG('O', 'S', '/', '2'),
(const void**)&tableData,
&len,
&tableContext,
&exists);
if (SUCCEEDED(hr)) {
if (exists && len >= 4) {
// Not checking against sizeof(mozilla::OS2Table) here because older
// versions of the table have different sizes; we only need the first
// two 16-bit fields here.
const mozilla::OS2Table* os2 =
reinterpret_cast<const mozilla::OS2Table*>(tableData);
mMetrics->aveCharWidth = ((gfxFloat)PRInt16(os2->xAvgCharWidth) /
fontMetrics.designUnitsPerEm) * mAdjustedSize;
// if the table is not available or if using hinted/pixel-snapped widths
if (mUseSubpixelPositions) {
mMetrics->aveCharWidth = 0;
hr = mFontFace->TryGetFontTable(DWRITE_MAKE_OPENTYPE_TAG('O', 'S', '/', '2'),
(const void**)&tableData,
&len,
&tableContext,
&exists);
if (SUCCEEDED(hr)) {
if (exists && len >= 4) {
// Not checking against sizeof(mozilla::OS2Table) here because older
// versions of the table have different sizes; we only need the first
// two 16-bit fields here.
const mozilla::OS2Table* os2 =
reinterpret_cast<const mozilla::OS2Table*>(tableData);
mMetrics->aveCharWidth =
PRInt16(os2->xAvgCharWidth) * mFUnitsConvFactor;
}
mFontFace->ReleaseFontTable(tableContext);
}
mFontFace->ReleaseFontTable(tableContext);
}
UINT32 ucs;
if (mMetrics->aveCharWidth < 1) {
ucs = L'x';
if (SUCCEEDED(mFontFace->GetGlyphIndicesA(&ucs, 1, &glyph)) &&
SUCCEEDED(mFontFace->GetDesignGlyphMetrics(&glyph, 1, &metrics))) {
mMetrics->aveCharWidth =
((gfxFloat)metrics.advanceWidth /
fontMetrics.designUnitsPerEm) * mAdjustedSize;
} else {
if (SUCCEEDED(mFontFace->GetGlyphIndicesA(&ucs, 1, &glyph))) {
mMetrics->aveCharWidth = MeasureGlyphWidth(glyph);
}
if (mMetrics->aveCharWidth < 1) {
// Let's just assume the X is square.
mMetrics->aveCharWidth =
((gfxFloat)fontMetrics.xHeight /
fontMetrics.designUnitsPerEm) * mAdjustedSize;
mMetrics->aveCharWidth = fontMetrics.xHeight * mFUnitsConvFactor;
}
}
ucs = L'0';
if (SUCCEEDED(mFontFace->GetGlyphIndicesA(&ucs, 1, &glyph)) &&
SUCCEEDED(mFontFace->GetDesignGlyphMetrics(&glyph, 1, &metrics))) {
mMetrics->zeroOrAveCharWidth =
((gfxFloat)metrics.advanceWidth /
fontMetrics.designUnitsPerEm) * mAdjustedSize;
} else {
if (SUCCEEDED(mFontFace->GetGlyphIndicesA(&ucs, 1, &glyph))) {
mMetrics->zeroOrAveCharWidth = MeasureGlyphWidth(glyph);
}
if (mMetrics->zeroOrAveCharWidth < 1) {
mMetrics->zeroOrAveCharWidth = mMetrics->aveCharWidth;
}
mMetrics->underlineOffset =
((gfxFloat)fontMetrics.underlinePosition /
fontMetrics.designUnitsPerEm) * mAdjustedSize;
mMetrics->underlineOffset =
fontMetrics.underlinePosition * mFUnitsConvFactor;
mMetrics->underlineSize =
((gfxFloat)fontMetrics.underlineThickness /
fontMetrics.designUnitsPerEm) * mAdjustedSize;
mMetrics->strikeoutOffset =
((gfxFloat)fontMetrics.strikethroughPosition /
fontMetrics.designUnitsPerEm) * mAdjustedSize;
mMetrics->strikeoutSize =
((gfxFloat)fontMetrics.strikethroughThickness /
fontMetrics.designUnitsPerEm) * mAdjustedSize;
fontMetrics.underlineThickness * mFUnitsConvFactor;
mMetrics->strikeoutOffset =
fontMetrics.strikethroughPosition * mFUnitsConvFactor;
mMetrics->strikeoutSize =
fontMetrics.strikethroughThickness * mFUnitsConvFactor;
mMetrics->superscriptOffset = 0;
mMetrics->subscriptOffset = 0;
mFUnitsConvFactor = float(mAdjustedSize / fontMetrics.designUnitsPerEm);
SanitizeMetrics(mMetrics, GetFontEntry()->mIsBadUnderlineFont);
#if 0
@ -697,26 +680,30 @@ gfxDWriteFont::GetGlyphWidth(gfxContext *aCtx, PRUint16 aGID)
return width;
}
DWRITE_GLYPH_METRICS glyphMetrics;
HRESULT hr;
if (mUseSubpixelPositions) {
hr = mFontFace->GetDesignGlyphMetrics(
&aGID, 1, &glyphMetrics, FALSE);
if (SUCCEEDED(hr)) {
width =
NS_lround(glyphMetrics.advanceWidth * mFUnitsConvFactor *
65536.0);
}
} else {
hr = mFontFace->GetGdiCompatibleGlyphMetrics(
FLOAT(mAdjustedSize), 1.0f, nsnull, FALSE,
&aGID, 1, &glyphMetrics, FALSE);
if (SUCCEEDED(hr)) {
width =
NS_lround(glyphMetrics.advanceWidth * mFUnitsConvFactor) << 16;
}
}
width = NS_lround(MeasureGlyphWidth(aGID) * 65536.0);
mGlyphWidths.Put(aGID, width);
return width;
}
gfxFloat
gfxDWriteFont::MeasureGlyphWidth(PRUint16 aGlyph)
{
DWRITE_GLYPH_METRICS metrics;
HRESULT hr;
if (mUseSubpixelPositions) {
hr = mFontFace->GetDesignGlyphMetrics(&aGlyph, 1, &metrics, FALSE);
if (SUCCEEDED(hr)) {
return metrics.advanceWidth * mFUnitsConvFactor;
}
} else {
hr = mFontFace->GetGdiCompatibleGlyphMetrics(
FLOAT(mAdjustedSize), 1.0f, nsnull,
gfxWindowsPlatform::GetPlatform()->DWriteMeasuringMode() ==
DWRITE_MEASURING_MODE_GDI_NATURAL,
&aGlyph, 1, &metrics, FALSE);
if (SUCCEEDED(hr)) {
return NS_lround(metrics.advanceWidth * mFUnitsConvFactor);
}
}
return 0;
}

View File

@ -98,6 +98,8 @@ protected:
cairo_scaled_font_t *CairoScaledFont();
gfxFloat MeasureGlyphWidth(PRUint16 aGlyph);
static void DestroyBlobFunc(void* userArg);
nsRefPtr<IDWriteFontFace> mFontFace;

View File

@ -2666,7 +2666,6 @@ gfxFontGroup::GetGeneration()
void
gfxFontGroup::UpdateFontList()
{
// if user font set is set, check to see if font list needs updating
if (mUserFontSet && mCurrGeneration != GetGeneration()) {
// xxx - can probably improve this to detect when all fonts were found, so no need to update list
mFonts.Clear();

View File

@ -58,6 +58,10 @@
#include "nsUnicodeRange.h"
#include "nsCRT.h"
#if defined(XP_WIN)
#include "gfxWindowsPlatform.h"
#endif
#define FloatToFixed(f) (65536 * (f))
#define FixedToFloat(f) ((f) * (1.0 / 65536.0))
// Right shifts of negative (signed) integers are undefined, as are overflows
@ -946,8 +950,12 @@ GetRoundOffsetsToPixels(gfxContext *aContext,
#if CAIRO_HAS_DWRITE_FONT // dwrite backend is not in std cairo releases yet
case CAIRO_FONT_TYPE_DWRITE:
// show_glyphs is implemented on the font and so is used for
// all surface types.
return;
// all surface types; however, it may pixel-snap depending on
// the dwrite rendering mode
if (gfxWindowsPlatform::GetPlatform()->DWriteMeasuringMode() ==
DWRITE_MEASURING_MODE_NATURAL) {
return;
}
#endif
case CAIRO_FONT_TYPE_QUARTZ:
// Quartz surfaces implement show_glyphs for Quartz fonts

View File

@ -158,6 +158,13 @@ NS_IMPL_ISUPPORTS1(D2DVRAMReporter, nsIMemoryReporter)
#define GFX_USE_CLEARTYPE_ALWAYS "gfx.font_rendering.cleartype.always_use_for_content"
#define GFX_DOWNLOADABLE_FONTS_USE_CLEARTYPE "gfx.font_rendering.cleartype.use_for_downloadable_fonts"
#define GFX_CLEARTYPE_PARAMS "gfx.font_rendering.cleartype_params."
#define GFX_CLEARTYPE_PARAMS_GAMMA "gfx.font_rendering.cleartype_params.gamma"
#define GFX_CLEARTYPE_PARAMS_CONTRAST "gfx.font_rendering.cleartype_params.enhanced_contrast"
#define GFX_CLEARTYPE_PARAMS_LEVEL "gfx.font_rendering.cleartype_params.cleartype_level"
#define GFX_CLEARTYPE_PARAMS_STRUCTURE "gfx.font_rendering.cleartype_params.pixel_structure"
#define GFX_CLEARTYPE_PARAMS_MODE "gfx.font_rendering.cleartype_params.rendering_mode"
#ifdef MOZ_FT2_FONTS
static FT_Library gPlatformFTLibrary = NULL;
#endif
@ -343,6 +350,8 @@ gfxWindowsPlatform::UpdateRenderMode()
mDWriteFactory = factory;
factory->Release();
SetupClearTypeParams(pref);
if (hr == S_OK)
reporter.SetSuccessful();
}
@ -790,6 +799,8 @@ gfxWindowsPlatform::FontsPrefsChanged(nsIPrefBranch *aPrefBranch, const char *aP
mUseClearTypeForDownloadableFonts = UNINITIALIZED_VALUE;
} else if (!strcmp(GFX_USE_CLEARTYPE_ALWAYS, aPref)) {
mUseClearTypeAlways = UNINITIALIZED_VALUE;
} else if (!strncmp(GFX_CLEARTYPE_PARAMS, aPref, strlen(GFX_CLEARTYPE_PARAMS))) {
SetupClearTypeParams(aPrefBranch);
} else {
clearTextFontCaches = PR_FALSE;
}
@ -803,6 +814,67 @@ gfxWindowsPlatform::FontsPrefsChanged(nsIPrefBranch *aPrefBranch, const char *aP
}
}
void
gfxWindowsPlatform::SetupClearTypeParams(nsIPrefBranch *aPrefBranch)
{
#if CAIRO_HAS_DWRITE_FONT
if (GetDWriteFactory()) {
// any missing prefs will default to invalid (-1) and be ignored;
// out-of-range values will also be ignored
FLOAT gamma = -1.0;
FLOAT contrast = -1.0;
FLOAT level = -1.0;
int geometry = -1;
int mode = -1;
PRInt32 value;
if (NS_SUCCEEDED(aPrefBranch->GetIntPref(GFX_CLEARTYPE_PARAMS_GAMMA,
&value))) {
if (value >= 1000 && value <= 2200) {
gamma = (FLOAT)value / 1000.0;
}
}
if (NS_SUCCEEDED(aPrefBranch->GetIntPref(GFX_CLEARTYPE_PARAMS_CONTRAST,
&value))) {
if (value >= 0 && value <= 1000) {
contrast = (FLOAT)value / 100.0;
}
}
if (NS_SUCCEEDED(aPrefBranch->GetIntPref(GFX_CLEARTYPE_PARAMS_LEVEL,
&value))) {
if (value >= 0 && value <= 100) {
level = (FLOAT)value / 100.0;
}
}
if (NS_SUCCEEDED(aPrefBranch->GetIntPref(GFX_CLEARTYPE_PARAMS_STRUCTURE,
&value))) {
if (value >= 0 && value <= 2) {
geometry = value;
}
}
if (NS_SUCCEEDED(aPrefBranch->GetIntPref(GFX_CLEARTYPE_PARAMS_MODE,
&value))) {
if (value >= 0 && value <= 5) {
mode = value;
}
}
cairo_dwrite_set_cleartype_params(gamma, contrast, level, geometry, mode);
switch (mode) {
case DWRITE_RENDERING_MODE_ALIASED:
case DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC:
mMeasuringMode = DWRITE_MEASURING_MODE_GDI_CLASSIC;
break;
case DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL:
mMeasuringMode = DWRITE_MEASURING_MODE_GDI_NATURAL;
break;
default:
mMeasuringMode = DWRITE_MEASURING_MODE_NATURAL;
break;
}
}
#endif
}
bool
gfxWindowsPlatform::IsOptimus()
{

View File

@ -238,9 +238,12 @@ public:
virtual void FontsPrefsChanged(nsIPrefBranch *aPrefBranch, const char *aPref);
void SetupClearTypeParams(nsIPrefBranch *aPrefBranch);
#ifdef CAIRO_HAS_DWRITE_FONT
IDWriteFactory *GetDWriteFactory() { return mDWriteFactory; }
inline PRBool DWriteEnabled() { return mUseDirectWrite; }
inline DWRITE_MEASURING_MODE DWriteMeasuringMode() { return mMeasuringMode; }
#else
inline PRBool DWriteEnabled() { return PR_FALSE; }
#endif
@ -270,6 +273,7 @@ private:
#ifdef CAIRO_HAS_DWRITE_FONT
nsRefPtr<IDWriteFactory> mDWriteFactory;
DWRITE_MEASURING_MODE mMeasuringMode;
#endif
#ifdef CAIRO_HAS_D2D_SURFACE
cairo_device_t *mD2DDevice;

View File

@ -1753,6 +1753,39 @@ pref("gfx.font_rendering.cleartype.use_for_downloadable_fonts", true);
// use cleartype rendering for all fonts always (win xp only)
pref("gfx.font_rendering.cleartype.always_use_for_content", false);
// ClearType tuning parameters for directwrite/d2d.
//
// Allows overriding of underlying registry values in:
// HKCU/Software/Microsoft/Avalon.Graphics/<display> (contrast and level)
// HKLM/Software/Microsoft/Avalon.Graphics/<display> (gamma, pixel structure)
// and selection of the ClearType/antialiasing mode.
//
// A value of -1 implies use the default value, otherwise value ranges
// follow registry settings:
// gamma [1000, 2200] default: based on screen, typically 2200 (== 2.2)
// enhanced contrast [0, 1000] default: 50
// cleartype level [0, 100] default: 100
// pixel structure [0, 2] default: 0 (flat/RGB/BGR)
// rendering mode [0, 5] default: 0
// 0 = use default for font & size;
// 1 = aliased;
// 2 = GDI Classic;
// 3 = GDI Natural Widths;
// 4 = Natural;
// 5 = Natural Symmetric
//
// See:
// http://msdn.microsoft.com/en-us/library/aa970267.aspx
// http://msdn.microsoft.com/en-us/library/dd368190%28v=VS.85%29.aspx
// Note: DirectWrite uses the "Enhanced Contrast Level" value rather than the
// "Text Contrast Level" value
pref("gfx.font_rendering.cleartype_params.gamma", -1);
pref("gfx.font_rendering.cleartype_params.enhanced_contrast", -1);
pref("gfx.font_rendering.cleartype_params.cleartype_level", -1);
pref("gfx.font_rendering.cleartype_params.pixel_structure", -1);
pref("gfx.font_rendering.cleartype_params.rendering_mode", -1);
pref("ui.key.menuAccessKeyFocuses", true);
// override double-click word selection behavior.