Hi Stephan, I try the r23267 tonight and noticed you've sumitted the old patch to SVN. The old patch caused rendering problem (see screen_r23267.png attached), sorry for that. I attached the new patch by this mail against r23267, it is same as the one on Haiku's timeline. >I think it fixes rendering of bitmap fonts in general, >but it should not support rotated text AFAIKT, >since that is only supported for vector fonts I think the Haiku's FontDemo can't show rotated text, but R5's FontDemo can show rotated text running on Haiku, have a look in screen_patch2.png attached. Thanks. Anthony On Jan 5, 2008 11:16 PM, Stephan Assmus <superstippi@xxxxxx> wrote: > Hello Anthony, > > Anthony Lee wrote (2007-12-31, 07:11:32 [+0100]): > > With the patch, now Haiku can display chinese well. You can find GPL'd > > CJK font on "http://sourceforge.net/projects/wqy"; > > > > The patch and screenshot attached to this mail. > > Thank you for your work! I am back home at my development machine. I will > have a look at this patch and some of the other discussion in the related > bug reports now. Sorry for the delay/silence and thanks again! :-) > > Best regards, > -Stephan > > >
Index: src/servers/app/FontEngine.cpp =================================================================== --- src/servers/app/FontEngine.cpp (revision 23267) +++ src/servers/app/FontEngine.cpp (working copy) @@ -332,12 +332,25 @@ } for (i = 0; i < bitmap.rows; i++) { sl.reset_spans(); - const uint8* p = buf; - for (j = 0; j < bitmap.width; j++) { - if (*p) - sl.add_cell(x + j, *p); - ++p; - } + + if (bitmap.pixel_mode == FT_PIXEL_MODE_MONO) { + // font has built-in mono bitmap + agg::bitset_iterator bits(buf, 0); + int j; + for (j = 0; j < bitmap.width; j++) { + if (bits.bit()) + sl.add_cell(x + j, agg::cover_full); + ++bits; + } + } else { + const uint8* p = buf; + for (j = 0; j < bitmap.width; j++) { + if (*p) + sl.add_cell(x + j, *p); + ++p; + } + } + buf += pitch; if (sl.num_spans()) { sl.finalize(y - i - 1); @@ -422,56 +435,59 @@ switch(fGlyphRendering) { case glyph_ren_native_mono: + fLastError = FT_Render_Glyph(fFace->glyph, FT_RENDER_MODE_MONO); + if (fLastError == 0) { + decompose_ft_bitmap_mono(fFace->glyph->bitmap, + fFace->glyph->bitmap_left, + kFlipY ? -fFace->glyph->bitmap_top : + fFace->glyph->bitmap_top, + kFlipY, + fScanlineBin, + fScanlineStorageBin); + fBounds.x1 = fScanlineStorageBin.min_x(); + fBounds.y1 = fScanlineStorageBin.min_y(); + fBounds.x2 = fScanlineStorageBin.max_x(); + fBounds.y2 = fScanlineStorageBin.max_y(); + fDataSize = fScanlineStorageBin.byte_size(); + fDataType = glyph_data_mono; + return true; + } + break; + + case glyph_ren_native_gray8: - fLastError = FT_Render_Glyph(fFace->glyph, - fGlyphRendering == glyph_ren_native_mono ? - FT_RENDER_MODE_MONO : FT_RENDER_MODE_NORMAL); + fLastError = FT_Render_Glyph(fFace->glyph, FT_RENDER_MODE_NORMAL); if (fLastError == 0) { - switch (fFace->glyph->bitmap.pixel_mode) { - case FT_PIXEL_MODE_MONO: - decompose_ft_bitmap_mono(fFace->glyph->bitmap, - fFace->glyph->bitmap_left, - kFlipY ? -fFace->glyph->bitmap_top - : fFace->glyph->bitmap_top, - kFlipY, fScanlineBin, fScanlineStorageBin); - fBounds.x1 = fScanlineStorageBin.min_x(); - fBounds.y1 = fScanlineStorageBin.min_y(); - fBounds.x2 = fScanlineStorageBin.max_x(); - fBounds.y2 = fScanlineStorageBin.max_y(); - fDataSize = fScanlineStorageBin.byte_size(); - fDataType = glyph_data_mono; - return true; - - case FT_PIXEL_MODE_GRAY: - decompose_ft_bitmap_gray8(fFace->glyph->bitmap, - fFace->glyph->bitmap_left, - kFlipY ? -fFace->glyph->bitmap_top - : fFace->glyph->bitmap_top, - kFlipY, fScanlineAA, fScanlineStorageAA); - fBounds.x1 = fScanlineStorageAA.min_x(); - fBounds.y1 = fScanlineStorageAA.min_y(); - fBounds.x2 = fScanlineStorageAA.max_x(); - fBounds.y2 = fScanlineStorageAA.max_y(); - fDataSize = fScanlineStorageAA.byte_size(); - fDataType = glyph_data_gray8; - return true; - - default: - break; - } + decompose_ft_bitmap_gray8(fFace->glyph->bitmap, + fFace->glyph->bitmap_left, + kFlipY ? -fFace->glyph->bitmap_top : + fFace->glyph->bitmap_top, + kFlipY, + fScanlineAA, + fScanlineStorageAA); + fBounds.x1 = fScanlineStorageAA.min_x(); + fBounds.y1 = fScanlineStorageAA.min_y(); + fBounds.x2 = fScanlineStorageAA.max_x(); + fBounds.y2 = fScanlineStorageAA.max_y(); + fDataSize = fScanlineStorageAA.byte_size(); + fDataType = glyph_data_gray8; + return true; } break; - + + case glyph_ren_outline: fPath.remove_all(); - if (decompose_ft_outline(fFace->glyph->outline, kFlipY, fPath)) { - agg::rect_d bounds = fPath.bounding_rect(); - fBounds.x1 = int(floor(bounds.x1)); - fBounds.y1 = int(floor(bounds.y1)); - fBounds.x2 = int(ceil(bounds.x2)); - fBounds.y2 = int(ceil(bounds.y2)); + if (decompose_ft_outline(fFace->glyph->outline, kFlipY, + fPath)) { + + agg::rect_d bnd = fPath.bounding_rect(); fDataSize = fPath.byte_size(); fDataType = glyph_data_outline; + fBounds.x1 = int(floor(bnd.x1)); + fBounds.y1 = int(floor(bnd.y1)); + fBounds.x2 = int(ceil(bnd.x2)); + fBounds.y2 = int(ceil(bnd.y2)); return true; } break;
Attachment:
screen_r23267.png
Description: PNG image
Attachment:
screen_patch2.png
Description: PNG image