dwrite: Implement grayscale rendering mode.
This commit is contained in:
parent
3f4a284f58
commit
26fbbdc48b
|
@ -199,6 +199,7 @@ struct dwrite_glyphbitmap {
|
|||
INT pitch;
|
||||
RECT bbox;
|
||||
BYTE *buf;
|
||||
DWRITE_TEXTURE_TYPE type;
|
||||
};
|
||||
|
||||
extern BOOL init_freetype(void) DECLSPEC_HIDDEN;
|
||||
|
@ -212,7 +213,7 @@ extern UINT16 freetype_get_glyphindex(IDWriteFontFace2*,UINT32,INT) DECLSPEC_HID
|
|||
extern BOOL freetype_has_kerning_pairs(IDWriteFontFace2*) DECLSPEC_HIDDEN;
|
||||
extern INT32 freetype_get_kerning_pair_adjustment(IDWriteFontFace2*,UINT16,UINT16) DECLSPEC_HIDDEN;
|
||||
extern void freetype_get_glyph_bbox(struct dwrite_glyphbitmap*) DECLSPEC_HIDDEN;
|
||||
extern void freetype_get_glyph_bitmap(struct dwrite_glyphbitmap*) DECLSPEC_HIDDEN;
|
||||
extern BOOL freetype_get_glyph_bitmap(struct dwrite_glyphbitmap*) DECLSPEC_HIDDEN;
|
||||
extern INT freetype_get_charmap_index(IDWriteFontFace2*,BOOL*) DECLSPEC_HIDDEN;
|
||||
extern INT32 freetype_get_glyph_advance(IDWriteFontFace2*,FLOAT,UINT16,DWRITE_MEASURING_MODE) DECLSPEC_HIDDEN;
|
||||
|
||||
|
|
|
@ -3622,6 +3622,7 @@ static void glyphrunanalysis_render(struct dwrite_glyphrunanalysis *analysis, DW
|
|||
glyph_bitmap.emsize = analysis->run.fontEmSize * analysis->ppdip;
|
||||
glyph_bitmap.nohint = analysis->rendering_mode == DWRITE_RENDERING_MODE_NATURAL ||
|
||||
analysis->rendering_mode == DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC;
|
||||
glyph_bitmap.type = type;
|
||||
bbox = &glyph_bitmap.bbox;
|
||||
|
||||
for (i = 0; i < analysis->run.glyphCount; i++) {
|
||||
|
@ -3629,6 +3630,7 @@ static void glyphrunanalysis_render(struct dwrite_glyphrunanalysis *analysis, DW
|
|||
FLOAT advance = analysis->advances[i];
|
||||
int x, y, width, height;
|
||||
BYTE *src, *dst;
|
||||
BOOL is_1bpp;
|
||||
|
||||
glyph_bitmap.index = analysis->run.glyphIndices[i];
|
||||
freetype_get_glyph_bbox(&glyph_bitmap);
|
||||
|
@ -3640,10 +3642,14 @@ static void glyphrunanalysis_render(struct dwrite_glyphrunanalysis *analysis, DW
|
|||
|
||||
width = bbox->right - bbox->left;
|
||||
height = bbox->bottom - bbox->top;
|
||||
glyph_bitmap.pitch = ((width + 31) >> 5) << 2;
|
||||
|
||||
if (type == DWRITE_TEXTURE_CLEARTYPE_3x1)
|
||||
glyph_bitmap.pitch = (width + 3) / 4 * 4;
|
||||
else
|
||||
glyph_bitmap.pitch = ((width + 31) >> 5) << 2;
|
||||
|
||||
glyph_bitmap.buf = src = heap_alloc_zero(height * glyph_bitmap.pitch);
|
||||
freetype_get_glyph_bitmap(&glyph_bitmap);
|
||||
is_1bpp = freetype_get_glyph_bitmap(&glyph_bitmap);
|
||||
|
||||
if (is_rtl)
|
||||
OffsetRect(bbox, origin_x - advance, 0);
|
||||
|
@ -3658,21 +3664,32 @@ static void glyphrunanalysis_render(struct dwrite_glyphrunanalysis *analysis, DW
|
|||
/* blit to analysis bitmap */
|
||||
dst = get_pixel_ptr(analysis->bitmap, type, bbox, &analysis->bounds);
|
||||
|
||||
/* convert 1bpp to 8bpp/24bpp */
|
||||
if (type == DWRITE_TEXTURE_CLEARTYPE_3x1) {
|
||||
for (y = 0; y < height; y++) {
|
||||
for (x = 0; x < width; x++)
|
||||
dst[3*x] = dst[3*x+1] = dst[3*x+2] = (src[x / 8] & masks[x % 8]) ? DWRITE_ALPHA_MAX : 0;
|
||||
src += get_dib_stride(width, 1);
|
||||
dst += (analysis->bounds.right - analysis->bounds.left) * 3;
|
||||
if (is_1bpp) {
|
||||
/* convert 1bpp to 8bpp/24bpp */
|
||||
if (type == DWRITE_TEXTURE_CLEARTYPE_3x1) {
|
||||
for (y = 0; y < height; y++) {
|
||||
for (x = 0; x < width; x++)
|
||||
dst[3*x] = dst[3*x+1] = dst[3*x+2] = (src[x / 8] & masks[x % 8]) ? DWRITE_ALPHA_MAX : 0;
|
||||
src += glyph_bitmap.pitch;
|
||||
dst += (analysis->bounds.right - analysis->bounds.left) * 3;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (y = 0; y < height; y++) {
|
||||
for (x = 0; x < width; x++)
|
||||
dst[x] = (src[x / 8] & masks[x % 8]) ? DWRITE_ALPHA_MAX : 0;
|
||||
src += get_dib_stride(width, 1);
|
||||
dst += analysis->bounds.right - analysis->bounds.left;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* at this point it's DWRITE_TEXTURE_CLEARTYPE_3x1 with 8bpp src bitmap */
|
||||
for (y = 0; y < height; y++) {
|
||||
for (x = 0; x < width; x++)
|
||||
dst[x] = (src[x / 8] & masks[x % 8]) ? DWRITE_ALPHA_MAX : 0;
|
||||
src += get_dib_stride(width, 1);
|
||||
dst += analysis->bounds.right - analysis->bounds.left;
|
||||
dst[3*x] = dst[3*x+1] = dst[3*x+2] = src[x];
|
||||
src += glyph_bitmap.pitch;
|
||||
dst += (analysis->bounds.right - analysis->bounds.left) * 3;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -510,10 +510,101 @@ void freetype_get_glyph_bbox(struct dwrite_glyphbitmap *bitmap)
|
|||
bitmap->bbox.bottom = -bbox.yMin;
|
||||
}
|
||||
|
||||
void freetype_get_glyph_bitmap(struct dwrite_glyphbitmap *bitmap)
|
||||
static BOOL freetype_get_aliased_glyph_bitmap(struct dwrite_glyphbitmap *bitmap, FT_Glyph glyph)
|
||||
{
|
||||
const RECT *bbox = &bitmap->bbox;
|
||||
int width = bbox->right - bbox->left;
|
||||
int height = bbox->bottom - bbox->top;
|
||||
|
||||
if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
|
||||
FT_OutlineGlyph outline = (FT_OutlineGlyph)glyph;
|
||||
const FT_Outline *src = &outline->outline;
|
||||
FT_Bitmap ft_bitmap;
|
||||
FT_Outline copy;
|
||||
|
||||
ft_bitmap.width = width;
|
||||
ft_bitmap.rows = height;
|
||||
ft_bitmap.pitch = bitmap->pitch;
|
||||
ft_bitmap.pixel_mode = FT_PIXEL_MODE_MONO;
|
||||
ft_bitmap.buffer = bitmap->buf;
|
||||
|
||||
/* Note: FreeType will only set 'black' bits for us. */
|
||||
if (pFT_Outline_New(library, src->n_points, src->n_contours, ©) == 0) {
|
||||
pFT_Outline_Copy(src, ©);
|
||||
pFT_Outline_Translate(©, -bbox->left << 6, bbox->bottom << 6);
|
||||
pFT_Outline_Get_Bitmap(library, ©, &ft_bitmap);
|
||||
pFT_Outline_Done(library, ©);
|
||||
}
|
||||
}
|
||||
else if (glyph->format == FT_GLYPH_FORMAT_BITMAP) {
|
||||
FT_Bitmap *ft_bitmap = &((FT_BitmapGlyph)glyph)->bitmap;
|
||||
BYTE *src = ft_bitmap->buffer, *dst = bitmap->buf;
|
||||
int w = min(bitmap->pitch, (ft_bitmap->width + 7) >> 3);
|
||||
int h = min(height, ft_bitmap->rows);
|
||||
|
||||
while (h--) {
|
||||
memcpy(dst, src, w);
|
||||
src += ft_bitmap->pitch;
|
||||
dst += bitmap->pitch;
|
||||
}
|
||||
}
|
||||
else
|
||||
FIXME("format %x not handled\n", glyph->format);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL freetype_get_aa_glyph_bitmap(struct dwrite_glyphbitmap *bitmap, FT_Glyph glyph)
|
||||
{
|
||||
const RECT *bbox = &bitmap->bbox;
|
||||
int width = bbox->right - bbox->left;
|
||||
int height = bbox->bottom - bbox->top;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
|
||||
FT_OutlineGlyph outline = (FT_OutlineGlyph)glyph;
|
||||
const FT_Outline *src = &outline->outline;
|
||||
FT_Bitmap ft_bitmap;
|
||||
FT_Outline copy;
|
||||
|
||||
ft_bitmap.width = width;
|
||||
ft_bitmap.rows = height;
|
||||
ft_bitmap.pitch = bitmap->pitch;
|
||||
ft_bitmap.pixel_mode = FT_PIXEL_MODE_GRAY;
|
||||
ft_bitmap.buffer = bitmap->buf;
|
||||
|
||||
/* Note: FreeType will only set 'black' bits for us. */
|
||||
if (pFT_Outline_New(library, src->n_points, src->n_contours, ©) == 0) {
|
||||
pFT_Outline_Copy(src, ©);
|
||||
pFT_Outline_Translate(©, -bbox->left << 6, bbox->bottom << 6);
|
||||
pFT_Outline_Get_Bitmap(library, ©, &ft_bitmap);
|
||||
pFT_Outline_Done(library, ©);
|
||||
}
|
||||
}
|
||||
else if (glyph->format == FT_GLYPH_FORMAT_BITMAP) {
|
||||
FT_Bitmap *ft_bitmap = &((FT_BitmapGlyph)glyph)->bitmap;
|
||||
BYTE *src = ft_bitmap->buffer, *dst = bitmap->buf;
|
||||
int w = min(bitmap->pitch, (ft_bitmap->width + 7) >> 3);
|
||||
int h = min(height, ft_bitmap->rows);
|
||||
|
||||
while (h--) {
|
||||
memcpy(dst, src, w);
|
||||
src += ft_bitmap->pitch;
|
||||
dst += bitmap->pitch;
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
}
|
||||
else
|
||||
FIXME("format %x not handled\n", glyph->format);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL freetype_get_glyph_bitmap(struct dwrite_glyphbitmap *bitmap)
|
||||
{
|
||||
FTC_ImageTypeRec imagetype;
|
||||
BOOL ret = FALSE;
|
||||
FT_Glyph glyph;
|
||||
|
||||
imagetype.face_id = bitmap->fontface;
|
||||
|
@ -523,45 +614,14 @@ void freetype_get_glyph_bitmap(struct dwrite_glyphbitmap *bitmap)
|
|||
|
||||
EnterCriticalSection(&freetype_cs);
|
||||
if (pFTC_ImageCache_Lookup(image_cache, &imagetype, bitmap->index, &glyph, NULL) == 0) {
|
||||
int width = bbox->right - bbox->left;
|
||||
int height = bbox->bottom - bbox->top;
|
||||
|
||||
if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
|
||||
FT_OutlineGlyph outline = (FT_OutlineGlyph)glyph;
|
||||
const FT_Outline *src = &outline->outline;
|
||||
FT_Bitmap ft_bitmap;
|
||||
FT_Outline copy;
|
||||
|
||||
ft_bitmap.width = width;
|
||||
ft_bitmap.rows = height;
|
||||
ft_bitmap.pitch = bitmap->pitch;
|
||||
ft_bitmap.pixel_mode = FT_PIXEL_MODE_MONO;
|
||||
ft_bitmap.buffer = bitmap->buf;
|
||||
|
||||
/* Note: FreeType will only set 'black' bits for us. */
|
||||
if (pFT_Outline_New(library, src->n_points, src->n_contours, ©) == 0) {
|
||||
pFT_Outline_Copy(src, ©);
|
||||
pFT_Outline_Translate(©, -bbox->left << 6, bbox->bottom << 6);
|
||||
pFT_Outline_Get_Bitmap(library, ©, &ft_bitmap);
|
||||
pFT_Outline_Done(library, ©);
|
||||
}
|
||||
}
|
||||
else if (glyph->format == FT_GLYPH_FORMAT_BITMAP) {
|
||||
FT_Bitmap *ft_bitmap = &((FT_BitmapGlyph)glyph)->bitmap;
|
||||
BYTE *src = ft_bitmap->buffer, *dst = bitmap->buf;
|
||||
int w = min(bitmap->pitch, (ft_bitmap->width + 7) >> 3);
|
||||
int h = min(height, ft_bitmap->rows);
|
||||
|
||||
while (h--) {
|
||||
memcpy(dst, src, w);
|
||||
src += ft_bitmap->pitch;
|
||||
dst += bitmap->pitch;
|
||||
}
|
||||
}
|
||||
if (bitmap->type == DWRITE_TEXTURE_CLEARTYPE_3x1)
|
||||
ret = freetype_get_aa_glyph_bitmap(bitmap, glyph);
|
||||
else
|
||||
FIXME("format %x not handled\n", glyph->format);
|
||||
ret = freetype_get_aliased_glyph_bitmap(bitmap, glyph);
|
||||
}
|
||||
LeaveCriticalSection(&freetype_cs);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
INT freetype_get_charmap_index(IDWriteFontFace2 *fontface, BOOL *is_symbol)
|
||||
|
@ -675,8 +735,9 @@ void freetype_get_glyph_bbox(struct dwrite_glyphbitmap *bitmap)
|
|||
memset(&bitmap->bbox, 0, sizeof(bitmap->bbox));
|
||||
}
|
||||
|
||||
void freetype_get_glyph_bitmap(struct dwrite_glyphbitmap *bitmap)
|
||||
BOOL freetype_get_glyph_bitmap(struct dwrite_glyphbitmap *bitmap)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
INT freetype_get_charmap_index(IDWriteFontFace2 *fontface, BOOL *is_symbol)
|
||||
|
|
Loading…
Reference in New Issue