mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
bug 642589 - expose prefs for tweaking DirectWrite/D2D antialiasing behavior. r=jdaggett
This commit is contained in:
parent
816d0ec482
commit
8e92dd97a6
@ -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);
|
||||
}
|
||||
|
@ -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(¶ms);
|
||||
|
||||
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(¶ms);
|
||||
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);
|
||||
|
||||
|
@ -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(¶ms);
|
||||
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.
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -98,6 +98,8 @@ protected:
|
||||
|
||||
cairo_scaled_font_t *CairoScaledFont();
|
||||
|
||||
gfxFloat MeasureGlyphWidth(PRUint16 aGlyph);
|
||||
|
||||
static void DestroyBlobFunc(void* userArg);
|
||||
|
||||
nsRefPtr<IDWriteFontFace> mFontFace;
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user